Skip to main content
Glama
Symbolic Algebra MCP Server

Symbolic Algebra MCP Server

Symbolic Algebra MCP Server (lag-sympy-mcp)

This is a maintained fork of sdiehl/sympy-mcp, which is no longer maintained upstream (Apache License 2.0). It adds algebra and calculus tools (factor_expression, expand_expression, cancel_expression, apart_expression, limit_expression, series_expansion, solve_inequality) and a safe expression parser; see MODIFICATIONS.md.

Sympy-MCP is a Model Context Protocol server for allowing LLMs to autonomously perform symbolic mathematics and computer algebra. It exposes numerous tools from SymPy's core functionality to MCP clients for manipulating mathematical expressions and equations.

Why?

Language models are absolutely abysmal at symbolic manipulation. They hallucinate variables, make up random constants, permute terms and generally make a mess. But we have computer algebra systems specifically built for symbolic manipulation, so we can use tool-calling to orchestrate a sequence of transforms so that the symbolic kernel does all the heavy lifting.

While you can certainly have an LLM generate Mathematica or Python code, if you want to use the LLM as an agent or on-the-fly calculator, it's a better experience to use the MCP server and expose the symbolic tools directly.

The server exposes a subset of symbolic mathematics capabilities including algebraic equation solving, integration and differentiation, vector calculus, tensor calculus for general relativity, and both ordinary and partial differential equations.

For example, you can ask it in natural language to solve a differential equation:

Solve the damped harmonic oscillator with forcing term: the mass-spring-damper system described by the differential equation where m is mass, c is the damping coefficient, k is the spring constant, and F(t) is an external force.

$$ m\frac{d^2x}{dt^2} + c\frac{dx}{dt} + kx = F(t) $$

Or involving general relativity:

Compute the trace of the Ricci tensor $R_{\mu\nu}$ using the inverse metric $g^{\mu\nu}$ for Anti-de Sitter spacetime to determine its constant scalar curvature $R$.

Related MCP server: Symath-MCP

Usage

You need uv first.

  • Homebrew : brew install uv

  • Curl : curl -LsSf https://astral.sh/uv/install.sh | sh

Then you can install and run the server with the following commands:

# Setup the project
git clone https://github.com/laguchoritarik/lag-sympy-mcp.git
cd lag-sympy-mcp
uv sync

# Install the server to Claude Desktop
uv run mcp install server.py

# Run the server
uv run mcp run server.py

You should see the server available in the Claude Desktop app now. For other clients, see below.

Claude Code setup

claude mcp add --scope user sympy-mcp -- uv --directory /ABSOLUTE_PATH_TO/lag-sympy-mcp run mcp run server.py

Replace /ABSOLUTE_PATH_TO/lag-sympy-mcp with the absolute path of your clone, then check the connection with claude mcp list.

If you want to do general relativity calculations, you need to install the einsteinpy library.

uv sync --group relativity

Available Tools

The sympy-mcp server provides the following tools for symbolic mathematics:

Tool

Tool ID

Description

Variable Introduction

intro

Introduces a variable with specified assumptions and stores it

Multiple Variables

intro_many

Introduces multiple variables with specified assumptions simultaneously

Expression Parser

introduce_expression

Parses an expression string using available local variables and stores it

LaTeX Printer

print_latex_expression

Prints a stored expression in LaTeX format, along with variable assumptions

Algebraic Solver

solve_algebraically

Solves an equation algebraically for a given variable over a given domain

Linear Solver

solve_linear_system

Solves a system of linear equations

Nonlinear Solver

solve_nonlinear_system

Solves a system of nonlinear equations

Function Variable

introduce_function

Introduces a function variable for use in differential equations

ODE Solver

dsolve_ode

Solves an ordinary differential equation

PDE Solver

pdsolve_pde

Solves a partial differential equation

Standard Metric

create_predefined_metric

Creates a predefined spacetime metric (e.g. Schwarzschild, Kerr, Minkowski)

Metric Search

search_predefined_metrics

Searches available predefined metrics

Tensor Calculator

calculate_tensor

Calculates tensors from a metric (Ricci, Einstein, Weyl tensors)

Custom Metric

create_custom_metric

Creates a custom metric tensor from provided components and symbols

Tensor LaTeX

print_latex_tensor

Prints a stored tensor expression in LaTeX format

Simplifier

simplify_expression

Simplifies a mathematical expression using SymPy's canonicalize function

Substitution

substitute_expression

Substitutes a variable with an expression in another expression

Integration

integrate_expression

Integrates an expression with respect to a variable

Differentiation

differentiate_expression

Differentiates an expression with respect to a variable

Coordinates

create_coordinate_system

Creates a 3D coordinate system for vector calculus operations

Vector Field

create_vector_field

Creates a vector field in the specified coordinate system

Curl

calculate_curl

Calculates the curl of a vector field

Divergence

calculate_divergence

Calculates the divergence of a vector field

Gradient

calculate_gradient

Calculates the gradient of a scalar field

Unit Converter

convert_to_units

Converts a quantity to given target units

Unit Simplifier

quantity_simplify_units

Simplifies a quantity with units

Matrix Creator

create_matrix

Creates a SymPy matrix from the provided data

Determinant

matrix_determinant

Calculates the determinant of a matrix

Matrix Inverse

matrix_inverse

Calculates the inverse of a matrix

Eigenvalues

matrix_eigenvalues

Calculates the eigenvalues of a matrix

Eigenvectors

matrix_eigenvectors

Calculates the eigenvectors of a matrix

Factorization

factor_expression

Factors an expression over Q (optionally over Q(i) or GF(p))

Expansion

expand_expression

Expands products and integer powers of sums

Rational Cancellation

cancel_expression

Puts a rational expression in canonical form p/q with common factors cancelled

Partial Fractions

apart_expression

Computes the partial fraction decomposition of a rational expression

Limit

limit_expression

Computes a limit at a finite point or at ±∞ (two-sided or one-sided)

Series Expansion

series_expansion

Computes a Taylor/Laurent expansion with or without the O(...) remainder

Inequality Solver

solve_inequality

Solves an inequality (or And/Or of inequalities) in one real variable

By default variables are predefined with assumptions (similar to how the symbols() function works in SymPy). Unless otherwise specified the defaut assumptions is that a variable is complex, commutative, term over the complex field $\mathbb{C}$.

Property

Value

commutative

true

complex

true

finite

true

infinite

false

Algebra and Calculus Tools

These tools work on expressions already stored with introduce_expression and return a new expression key (print it with print_latex_expression), except solve_inequality, which returns the LaTeX of the solution set, like solve_algebraically. factor_expression, expand_expression, cancel_expression and apart_expression apply to both sides of an equation and to each entry of a matrix.

Tool

Parameters

Example input → output

factor_expression

expr_key, gaussian=false, modulus=null (prime)

x**6 - 1 → (x - 1)(x + 1)(x² - x + 1)(x² + x + 1); x**2 + 1 with gaussian=true → (x - i)(x + i)

expand_expression

expr_key

(x + 1)**3 → x³ + 3x² + 3x + 1

cancel_expression

expr_key

(x**2 - 1)/(x**2 - 2*x + 1) → (x + 1)/(x - 1) (formal cancellation)

apart_expression

expr_key, var_name (required if several variables)

1/(x**2 - 1) → 1/(2(x - 1)) - 1/(2(x + 1))

limit_expression

expr_key, var_name, point, direction = "+-" (default) / "+" / "-"

sin(x)/x, "0" → 1; (1 + 1/x)**x, "oo" → e; 1/x, "0" → error (one-sided limits differ)

series_expansion

expr_key, var_name, point="0", order=6 (1–50), remove_order_term=false

exp(x), order 4 → 1 + x + x²/2 + x³/6 + O(x⁴)

solve_inequality

expr_key, var_name

x**2 - 1 > 0 → (-∞, -1) ∪ (1, ∞); And(x > 0, x**2 < 4) → (0, 2)

Notes:

  • limit_expression reports an error, rather than a value, when the limit does not exist: one-sided limits that differ (1/x, Abs(x)/x at 0) or oscillation (sin(x) at oo).

  • Inequalities are solved over the reals. Write a double inequality a < f(x) < b as And(a < f(x), f(x) < b); Python's chained comparison is not supported by SymPy.

  • The point arguments of limit_expression and series_expansion are not passed to parse_expr. They are parsed with Python's ast module against an allow-list: numbers, introduced variables, oo/inf/infinity/zoo/pi/E/I, + - * / ** ^, and the functions sqrt, exp, log, sin, cos, tan, Rational. Anything else (attribute access, subscripts, strings, keyword arguments, other calls, very large exact powers, inputs over 256 characters) is rejected before evaluation.

Claude Desktop Setup

Normally the mcp install command will automatically add the server to the claude_desktop_config.json file. If it doesn't you need to find the config file and add the following:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Add the following to the mcpServers object, replacing /ABSOLUTE_PATH_TO_SYMPY_MCP/server.py with the absolute path to the sympy-mcp server.py file.

{
  "mcpServers": {
    "sympy-mcp": {
      "command": "/opt/homebrew/bin/uv",
      "args": [
        "run",
        "--with",
        "einsteinpy",
        "--with",
        "mcp[cli]",
        "--with",
        "pydantic",
        "--with",
        "sympy",
        "mcp",
        "run",
        "/ABSOLUTE_PATH_TO_SYMPY_MCP/server.py"
      ]
    }
  }
}

Cursor Setup

In your ~/.cursor/mcp.json, add the following, where ABSOLUTE_PATH_TO_SYMPY_MCP is the path to the sympy-mcp server.py file.

{
  "mcpServers": {
    "sympy-mcp": {
      "command": "/opt/homebrew/bin/uv",
      "args": [
        "run",
        "--with",
        "einsteinpy",
        "--with",
        "mcp[cli]",
        "--with",
        "pydantic",
        "--with",
        "sympy",
        "mcp",
        "run",
        "/ABSOLUTE_PATH_TO_SYMPY_MCP/server.py"
      ]
    }
  }
}

VS Code Setup

VS Code and VS Code Insiders now support MCPs in agent mode. For VS Code, you may need to enable Chat > Agent: Enable in the settings.

  1. One-click Setup:

Install in VS Code

Install in VS Code Insiders

OR manually add the config to your settings.json (global):

{
  "mcp": {
    "servers": {
      "sympy-mcp": {
        "command": "uv",
        "args": [
          "run",
          "--with",
          "einsteinpy",
          "--with",
          "mcp[cli]",
          "--with",
          "pydantic",
          "--with",
          "sympy",
          "mcp",
          "run",
          "/ABSOLUTE_PATH_TO_SYMPY_MCP/server.py"
        ]
      }
    }
  }
}
  1. Click "Start" above the server config switch to agent mode in the chat, and try commands like "integrate x^2" or "solve x^2 = 1" to get started.

HTTP Transport (Streamable HTTP / SSE)

The server supports MCP over HTTP using the streamable-http transport introduced in MCP spec 2025-03-26. This replaces the legacy SSE transport and exposes a single /mcp endpoint that clients connect to over HTTP.

This is the recommended transport when running the server as a standalone process or in a container, because it allows any HTTP-capable MCP client to connect without needing to launch the server as a subprocess.

# Run locally with HTTP transport
uv run python server.py --transport streamable-http

# Override host/port
uv run python server.py --transport streamable-http --mcp-host 127.0.0.1 --mcp-port 9000

The legacy --transport sse flag is still supported for backward compatibility.

A /healthcheck endpoint is also exposed that runs a full MCP protocol round-trip (initialize → tools/list → session teardown) and returns {"status": "ok", "tool_count": N}.

Running in Container

You can build and run the server using Docker locally:

# Build the Docker image
docker build -t sympy-mcp .

# Run the Docker container
docker run -p 8081:8081 sympy-mcp

Or use Docker Compose from the docker/ directory:

cd docker
docker compose up -d --build

Alternatively, you can pull the pre-built image from GitHub Container Registry:

# Pull the latest image
docker pull ghcr.io/laguchoritarik/lag-sympy-mcp:main

# Run the container
docker run -p 8081:8081 --rm ghcr.io/laguchoritarik/lag-sympy-mcp:main

To configure Claude Desktop to launch the Docker container, edit your claude_desktop_config.json file:

{
  "mcpServers": {
    "sympy-mcp": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "-p",
        "8081:8081",
        "--rm",
        "sympy-mcp"
      ]
    }
  }
}

Or to use the pre-built container from GitHub:

{
  "mcpServers": {
    "sympy-mcp": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "-p",
        "8081:8081",
        "--rm",
        "ghcr.io/laguchoritarik/lag-sympy-mcp:main"
      ]
    }
  }
}

This configuration tells Claude Desktop to launch the Docker container when needed. Make sure to build the Docker image (docker build -t sympy-mcp .) before using Claude Desktop with this configuration.

The other installation methods can also be adapted to work with Docker if you change the uv command to use the docker run command instead.

Example Interaction 1 : Differential Equations

Here's an example of how the tool-calling works in a conversation with an AI assistant using this MCP server:

User: Solve the damped harmonic oscillator with forcing term: the mass-spring-damper system described by the differential equation where m is mass, c is the damping coefficient, k is the spring constant, and F(t) is an external force.

$$ m\frac{d^2x}{dt^2} + c\frac{dx}{dt} + kx = F(t) $$

Assistant: (Internal tool call) intro_many to introduce variables:

{
  "variables": [
    {"var_name": "t", "pos_assumptions": ["real"], "neg_assumptions": []},
    {"var_name": "m", "pos_assumptions": ["real", "positive"], "neg_assumptions": []},
    {"var_name": "c", "pos_assumptions": ["real", "positive"], "neg_assumptions": []},
    {"var_name": "k", "pos_assumptions": ["real", "positive"], "neg_assumptions": []}
  ]
}

Assistant: (Internal tool call) introduce_function to define x(t):

{
  "func_name": "x"
}

Assistant: (Internal tool call) introduce_expression to create the differential equation:

{
  "expr_str": "Eq(m*Derivative(x(t), t, t) + c*Derivative(x(t), t) + k*x(t), F(t))"
}

Assistant: (Internal tool call) print_latex_expression to display the equation nicely:

{
  "expr_key": "expr_12"
}

Result:

$$ c \frac{d}{d t} x{\left(t \right)} + k x{\left(t \right)} + m \frac{d^{2}}{d t^{2}} x{\left(t \right)} = F{\left(t \right)} $$

Assistant: (Internal tool call) introduce_function to define F(t):

{
  "func_name": "F"
}

Assistant: (Internal tool call) dsolve_ode to solve the differential equation:

{
  "expr_key": "expr_12",
  "func_name": "x"
}

Result:

$$ x{\left(t \right)} = C_{1} e^{\frac{t \left(- c + \sqrt{c^{2} - 4 k m}\right)}{2 m}} + C_{2} e^{- \frac{t \left(c + \sqrt{c^{2} - 4 k m}\right)}{2 m}} + \cdots $$

Example Interaction 2: General Relativity

User: Compute the trace of the Ricci tensor $R_{\mu\nu}$ using the inverse metric $g^{\mu\nu}$ for Anti-de Sitter spacetime to determine its constant scalar curvature $R$.

Assistant: (Internal tool call) create_predefined_metric to create the Anti-de Sitter metric:

{
  "metric_name": "AntiDeSitter"
}

Assistant: (Internal tool call) calculate_tensor to calculate the Ricci tensor:

{
  "metric_key": "metric_AntiDeSitter",
  "tensor_type": "RICCI_TENSOR",
  "simplify_result": true
}

Assistant: (Internal tool call) print_latex_tensor to display the Ricci tensor:

{
  "tensor_key": "riccitensor_metric_AntiDeSitter"
}

Result:

$$ \left[\begin{matrix}3 & 0 & 0 & 0\\0 & - 3 \cos^{2}{\left(t \right)} & 0 & 0\\0 & 0 & - 3 \cos^{2}{\left(t \right)} \sinh^{2}{\left(\chi \right)} & 0\\0 & 0 & 0 & - 3 \sin^{2}{\left(\theta \right)} \cos^{2}{\left(t \right)} \sinh^{2}{\left(\chi \right)}\end{matrix}\right] $$

Assistant: (Internal tool call) calculate_tensor to calculate the Ricci scalar:

{
  "metric_key": "metric_AntiDeSitter",
  "tensor_type": "RICCI_SCALAR",
  "simplify_result": true
}

Assistant: (Internal tool call) print_latex_tensor to display the Ricci scalar:

{
  "tensor_key": "ricciscalar_metric_AntiDeSitter"
}

Result:

$$ -12 $$

Example Interaction 3: Coupled ODE System (Fluid Dynamics)

This example demonstrates solving a coupled system of ODEs and verifying the solution against an algebraic steady-state analysis, a task where LLMs typically hallucinate without a CAS to ground each step.

User:

Use the sympy-mcp tools to solve this symbolically. Do not compute by hand.

Two cylindrical tanks are connected by a pipe. Tank 1 has cross-sectional area A₁ = 2 m² and receives a constant inflow of Q = 0.5 m³/s. Water drains from Tank 1 into Tank 2 through a pipe with flow rate proportional to the height difference: q₁₂ = k·(h₁ - h₂) where k = 0.3 m²/s. Tank 2 has cross-sectional area A₂ = 1 m² and drains to the outside at rate q₂ = k·h₂ with the same k.

Set up and solve the coupled system of ODEs for the water heights h₁(t) and h₂(t), starting from empty tanks (h₁(0) = 0, h₂(0) = 0). Then find the steady-state heights as t → ∞ by solving the equilibrium equations algebraically, and verify they match the long-term solution of the ODEs.

Assistant: (Internal tool chain)

  1. intro_many: introduce t, k, A1, A2, Q with real/positive assumptions

  2. introduce_function × 2: introduce h1(t) and h2(t) as unknown functions

  3. introduce_expression × 2: encode the mass-balance ODEs:

$$A_1 \frac{dh_1}{dt} = Q - k(h_1 - h_2), \quad A_2 \frac{dh_2}{dt} = k(h_1 - h_2) - k h_2$$

  1. substitute_expression: substitute numeric values for k, A1, A2, Q

  2. dsolve_ode × 2: solve the coupled system; apply initial conditions via substitute_expression

  3. introduce_expression × 2: encode equilibrium equations (derivatives set to zero)

  4. solve_linear_system: solve the 2×2 algebraic system for h1*, h2*

  5. print_latex_expression: display both the time-domain solution and the steady-state values

Security Disclaimer

This server runs on your computer and gives the language model access to run Python logic. Notably it uses Sympy's parse_expr to parse mathematical expressions, which is uses eval under the hood, effectively allowing arbitrary code execution. By running the server, you are trusting the code that Claude generates. Running in the Docker image is slightly safer, but it's still a good idea to review the code before running it.

parse_expr call sites

The following tools pass client-supplied strings to parse_expr with SymPy's default global namespace (which includes Python builtins such as __import__, open, eval, exec):

  • introduce_expression (expr_str)

  • integrate_expression (lower_bound, upper_bound)

  • create_vector_field (component strings)

  • create_matrix (string entries)

  • convert_to_units (target unit strings)

  • create_custom_metric (component strings)

For example introduce_expression("__import__('os').getpid()") executes the call. Passing global_dict={} is not a mitigation: eval re-inserts the complete __builtins__ module into an empty globals dictionary, and object attribute traversal (obj.__class__.__mro__...) remains available regardless of the namespace. SymPy documents parse_expr/sympify as unsafe on untrusted input. Resource exhaustion is also possible (e.g. 10**10**10), and no time limit is applied to any tool. With the HTTP transports the server binds to 0.0.0.0 by default, which exposes these risks to the network; prefer --mcp-host 127.0.0.1 or the stdio transport.

The algebra/calculus tools added in this fork (factor_expression, expand_expression, cancel_expression, apart_expression, limit_expression, series_expansion, solve_inequality) never call parse_expr, sympify or eval themselves; their only string inputs are parsed by the allow-list parser described above. They still operate on expressions that were created through introduce_expression, so they do not remove the risk of that entry point.

License

Copyright 2025 Stephen Diehl.

This project is licensed under the Apache 2.0 License. See the LICENSE file for details.

Available Tools

39 tools
apart_expressionA

Computes the partial fraction decomposition of a rational expression using SymPy's apart.

Args:
    expr_key: The key of the expression (previously introduced) to decompose.
    var_name: The variable (previously introduced) to decompose with respect to.
        Required when the expression has several variables.

Example:
    intro("x", [Assumption.REAL], [])
    expr_key = introduce_expression("1/(x**2 - 1)")
    result_key = apart_expression(expr_key, "x")
    # -1/(2(x + 1)) + 1/(2(x - 1))

Returns:
    A key for the decomposed expression.
NameRequiredDescriptionDefault
expr_keyYes
var_nameNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Without annotations, the description carries the burden and does well: it names the underlying operation, explains that expr_key and var_name refer to previously introduced objects, and states that a key for the decomposed expression is returned. It omits failure modes or error conditions, but for a pure symbolic computation that is a minor gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded, followed by compact argument notes, a useful example, and a return note. Every section contributes directly to correct invocation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is complete enough to call the tool correctly: inputs, optionality context, example, and return key are all covered. Since an output schema exists, it need not detail return structure, and the remaining gap around error behavior is minor.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It does: expr_key is defined as the key of a previously introduced expression, and var_name is defined as the variable to decompose with respect to, including when it is required.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and mathematical resource: computes partial fraction decomposition of a rational expression using SymPy's apart. This is clearly distinguishable from sibling operations such as factor_expression, expand_expression, or cancel_expression.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides a concrete usage example and clarifies that var_name is required when the expression has several variables. It does not explicitly compare against alternatives, but the operation's purpose makes appropriate use clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calculate_curlA

Calculates the curl of a vector field using SymPy's curl function.

Args:
    vector_field_key: The key of the vector field expression.

Example:
    # First create a coordinate system
    create_coordinate_system("R")

    # Create a vector field F = (y, -x, 0)
    vector_field = create_vector_field("R", "R_y", "-R_x", "0")

    # Calculate curl
    curl_result = calculate_curl(vector_field)
    # Returns (0, 0, -2)

Returns:
    A key for the curl expression.
NameRequiredDescriptionDefault
vector_field_keyYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden. It does disclose that the result is a key rather than an expanded expression, but there is a mild inconsistency: the prose says 'Returns: A key for the curl expression' while the example comment says '# Returns (0, 0, -2)'. It says nothing about error conditions, dimensional requirements, or whether the expression is auto-simplified.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in a single sentence, followed by Args/Example/Returns sections. The example is multi-line but earns its place by demonstrating the required call sequence rather than merely restating parameters.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value detail is covered elsewhere, and the description still names the return type. For a one-parameter tool with a clear prerequisite workflow, the main remaining gap is unstated failure modes (e.g., non-3D fields).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% – the schema only names 'vector_field_key' as a string. The description compensates by defining it as 'the key of the vector field expression' and the example shows it is the value returned by create_vector_field, so the agent knows where to obtain it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Calculates the curl of a vector field using SymPy's curl function.' An agent can distinguish this from calculate_divergence and calculate_gradient by name, though the description never explicitly contrasts them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The worked example makes the prerequisite chain explicit: create_coordinate_system first, then create_vector_field, then calculate_curl. That is real usage guidance for a stateful CAS tool, though there are no stated exclusions or conditions where curl is inapplicable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calculate_divergenceA

Calculates the divergence of a vector field using SymPy's divergence function.

Args:
    vector_field_key: The key of the vector field expression.

Example:
    # First create a coordinate system
    create_coordinate_system("R")

    # Create a vector field F = (x, y, z)
    vector_field = create_vector_field("R", "R_x", "R_y", "R_z")

    # Calculate divergence
    div_result = calculate_divergence(vector_field)
    # Returns 3

Returns:
    A key for the divergence expression.
NameRequiredDescriptionDefault
vector_field_keyYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It does disclose that the result is a key for the divergence expression, and the example suggests the output may be a simplified scalar (e.g., 3), but it does not describe error conditions, required context beyond the example, or any side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the purpose, then uses structured Args, Example, and Returns sections. It is appropriately sized for a simple one-parameter tool, though the example is longer than strictly necessary.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter calculation tool with an output schema, the description provides enough context to call it correctly: the purpose, parameter meaning, an end-to-end example, and the return type. Minor gaps remain around explicit usage criteria and error handling.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It defines vector_field_key as the key of the vector field expression, and the example shows how such a key is produced via create_vector_field, but it does not specify the expected key format or validate what happens if the key is invalid.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: it calculates the divergence of a vector field, and names SymPy as the underlying implementation. It is clear what the tool does, though it does not explicitly contrast itself with sibling operations like calculate_curl or calculate_gradient.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The example demonstrates the expected workflow: create a coordinate system, create a vector field, then calculate divergence. However, there is no explicit statement about when to use this tool versus alternatives such as calculate_curl, nor are prerequisites or exclusions spelled out beyond the example.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calculate_gradientA

Calculates the gradient of a scalar field using SymPy's gradient function.

Args:
    scalar_field_key: The key of the scalar field expression.

Example:
    # First create a coordinate system
    create_coordinate_system("R")

    # Create a scalar field f = x^2 + y^2 + z^2
    scalar_field = introduce_expression("R_x**2 + R_y**2 + R_z**2")

    # Calculate gradient
    grad_result = calculate_gradient(scalar_field)
    # Returns (2x, 2y, 2z)

Returns:
    A key for the gradient vector field expression.
NameRequiredDescriptionDefault
scalar_field_keyYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses that the result is a key referencing a gradient vector field expression and gives a concrete expected output (2x, 2y, 2z), which is useful. It does not state what happens on invalid keys, missing coordinate systems, or whether any state is mutated — meaningful gaps for a tool with zero annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose is front-loaded in one sentence, followed by Args, a compact example, and Returns. The example is multi-step but each line illustrates a required precondition, so it mostly earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be spelled out, yet the description adds a helpful prose summary of the return. Combined with the prerequisite example, an agent has what it needs to invoke the tool; only error/failure behavior is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must define the single parameter. 'The key of the scalar field expression' plus the example showing a key produced by introduce_expression gives the agent enough to supply a valid value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence states a specific verb and resource: it computes the gradient of a scalar field, distinguishing it from siblings like calculate_curl and calculate_divergence which operate on vector fields. It stops short of explicitly naming those siblings, so an agent must infer the boundary from domain knowledge.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The worked example implicitly conveys the prerequisites (a coordinate system must exist, the scalar field must come from introduce_expression) and shows the correct call order. There is no explicit 'use this instead of X' or exclusion guidance, but the ordering context is clear enough to call the tool correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calculate_tensorC

Calculates a tensor from a metric using einsteinpy.symbolic.

NameRequiredDescriptionDefault
metric_keyYes
tensor_typeYes
simplify_resultNo

Output Schema

NameRequiredDescription
resultYes

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It does not state whether the tool is read-only, whether it depends on prior state, what tensor types are supported, or what happens when simplify_result is enabled or disabled.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence with no filler. It is concise, though its brevity contributes to the surrounding specification gaps.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Although an output schema exists and covers return values, the input side is severely under-specified: three parameters have zero schema descriptions, no enum values are exposed for tensor_type, and no annotations exist. The description does far too little to compensate for this complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description adds almost no meaning beyond the schema. It only hints that a metric is involved, while tensor_type, metric_key format, and simplify_result behavior remain completely undefined.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: calculates a tensor from a metric using einsteinpy.symbolic. However, it does not distinguish this tool from sibling tensor-related tools such as print_latex_tensor, nor does it clarify what kinds of tensors can be calculated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus alternatives, no prerequisites, and no mention of required state such as an existing metric. The agent must infer usage entirely from the name and schema.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

cancel_expressionA

Puts a rational expression in canonical form p/q with common factors cancelled.

Uses SymPy's cancel function. Cancellation is formal: (x**2 - 1)/(x - 1)
becomes x + 1, even though the original is undefined at x = 1.

Args:
    expr_key: The key of the expression (previously introduced) to cancel.

Example:
    intro("x", [Assumption.REAL], [])
    expr_key = introduce_expression("(x**2 - 1)/(x**2 - 2*x + 1)")
    result_key = cancel_expression(expr_key)
    # (x + 1)/(x - 1)

Returns:
    A key for the simplified rational expression.
NameRequiredDescriptionDefault
expr_keyYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It helpfully discloses that cancellation is formal and may change the domain, e.g. (x**2 - 1)/(x - 1) becomes x + 1 despite the original being undefined at x = 1. It does not state whether the original expression is mutated, how errors are handled for invalid keys, or what side effects occur.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose, followed by a concise Args section, a concrete example, and a short Returns note. Every section earns its place by clarifying usage or output for a new user.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has one parameter and an output schema, so the description does not need to explain return values in depth. It supplies the key mathematical caveat and an example, leaving only minor gaps around error behavior and interactions with sibling simplification tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the input schema only names the parameter as Expr Key. The description compensates well by explaining that expr_key is the key of a previously introduced expression to cancel, which is sufficient semantic guidance for the single required parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: canonicalizing a rational expression by cancelling common factors into p/q form. It clearly distinguishes the operation from general simplification through its formal cancellation example, but it does not name or contrast with sibling tools such as factor_expression or apart_expression.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The example implies the intended workflow: first introduce an expression, then call cancel_expression with its key. However, there is no explicit guidance on when to use this tool versus simplify_expression, factor_expression, expand_expression, or apart_expression, so usage must be inferred.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

convert_to_unitsA

Converts a quantity to the given target units using sympy.physics.units.convert_to.

Args:
    expr_key: The key of the expression (previously introduced) to convert.
    target_units: List of unit names as strings (e.g., ["meter", "1/second"]).
    unit_system: Optional unit system (from UnitSystem enum). Defaults to SI.

The following units are available by default:
    SI base units: meter, second, kilogram, ampere, kelvin, mole, candela
    Length: kilometer, millimeter
    Mass: gram
    Energy: joule
    Force: newton
    Pressure: pascal
    Power: watt
    Electric: coulomb, volt, ohm, farad, henry
    Constants: speed_of_light, gravitational_constant, planck

IMPORTANT: For compound units like meter/second, you must separate the numerator and
denominator into separate units in the list. For example:
- For meter/second: use ["meter", "1/second"]
- For newton*meter: use ["newton", "meter"]
- For kilogram*meter²/second²: use ["kilogram", "meter**2", "1/second**2"]

Example:
    # Convert speed of light to kilometers per hour
    expr_key = introduce_expression("speed_of_light")
    result = convert_to_units(expr_key, ["kilometer", "1/hour"])
    # Returns approximately 1.08e9 kilometer/hour

    # Convert gravitational constant to CGS units
    expr_key = introduce_expression("gravitational_constant")
    result = convert_to_units(expr_key, ["centimeter**3", "1/gram", "1/second**2"], UnitSystem.CGS)

SI prefixes (femto, pico, nano, micro, milli, centi, deci, deca, hecto, kilo, mega, giga, tera)
can be used directly with base units.

Returns:
    A key for the converted expression, or an error message.
NameRequiredDescriptionDefault
expr_keyYes
unit_systemNo
target_unitsYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the transparency burden and does well: it discloses the compound-unit list syntax, available units, optional unit system, and that the return is a key or error message. It does not explicitly state whether the original expression is modified or whether a new expression key is persisted, but overall behavioral context is strong for a computation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but justified by the complexity of unit conversion. It is front-loaded with the purpose, then structured into args, available units, important formatting rules, and examples with no wasted prose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complex unit syntax and 0% schema description coverage, the description supplies the parameter meanings, unit inventory, compound-unit rules, and examples needed to invoke the tool correctly. An output schema exists, so the brief return note is sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate, and it does thoroughly. It explains expr_key, target_units with compound-unit syntax and examples, and unit_system with default SI, going well beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: converting a previously introduced expression to target units via sympy.physics.units.convert_to. It is clear what the tool does, but it does not explicitly differentiate itself from the sibling quantity_simplify_units or other unit-related tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by requiring a previously introduced expr_key and by giving examples, but it never states when to use this tool versus alternatives. There are no explicit exclusions or guidance on choosing between convert_to_units and quantity_simplify_units.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_coordinate_systemA

Creates a 3D coordinate system for vector calculus operations.

Args:
    name: The name for the coordinate system.
    coord_names: Optional list of coordinate names (3 names for x, y, z).
                If not provided, defaults to [name+'_x', name+'_y', name+'_z'].

Example:
    # Create a coordinate system
    coord_sys = create_coordinate_system("R")
    # Creates a coordinate system R with coordinates R_x, R_y, R_z

    # Create a coordinate system with custom coordinate names
    coord_sys = create_coordinate_system("C", ["rho", "phi", "z"])

Returns:
    The name of the created coordinate system.
NameRequiredDescriptionDefault
nameYes
coord_namesNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the creation action and the return value (the name), and documents the default coordinate naming behavior. However, it does not disclose whether the coordinate system is persisted in global state, what happens if the name already exists, or any other side effects or error conditions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose, then structured with Args, Example, and Returns sections. It is appropriately sized for a creation tool with two parameters. Minor redundancy exists because the output schema already covers the return value, but the overall structure is clear and useful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so the description need not explain return values, yet it does so redundantly. For a mutation tool with no annotations, the description should ideally mention side effects, persistence, or error behavior. It covers parameters well but leaves behavioral gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the description fully compensates by documenting both parameters: 'name' and 'coord_names', including the default behavior for coord_names ([name+'_x', name+'_y', name+'_z']) and the expected list length (3 names). The examples further clarify usage with concrete values.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb and resource: 'Creates a 3D coordinate system for vector calculus operations.' This distinguishes it from most siblings, but it does not explicitly differentiate it from related creation tools like create_custom_metric or create_vector_field.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'for vector calculus operations' implies when the tool is useful, but there are no explicit guidelines about when to prefer this tool over alternatives, nor any exclusions or prerequisites. The examples help clarify invocation but not tool selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_custom_metricC

Creates a custom metric tensor from provided components and symbols.

NameRequiredDescriptionDefault
configNoll
symbolsYes
componentsYes

Output Schema

NameRequiredDescription
resultYes

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must carry the full behavioral burden. It states that the tool creates a tensor, but does not describe permissions, state changes, coordinate-system requirements, or other behavioral traits relevant to a creation operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence with no wasted wording. It is efficient, though its brevity contributes to the missing detail captured in other dimensions.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a custom-metric creation tool with no annotations and 0% schema description coverage, the description omits essential context about parameter meaning and usage relative to predefined metrics. The existence of an output schema covers return values, but it does not compensate for the missing input and behavioral context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for all three parameters, and the description only restates that components and symbols are provided. It does not explain the nested array format of components, what symbols represent, or what the config enum values 'll' and 'uu' mean.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: creates a custom metric tensor from provided components and symbols. It is clear what the tool does, but it does not distinguish itself from sibling tools such as create_predefined_metric or search_predefined_metrics.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit guidance on when to use this tool versus create_predefined_metric or search_predefined_metrics. The word 'custom' implies an alternative to predefined metrics, but the description gives no conditions, exclusions, or prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_matrixA

Creates a SymPy matrix from the provided data.

Args:
    matrix_data: A list of lists representing the rows and columns of the matrix.
                Each element can be a number or a string expression.
    matrix_var_name: Optional name for storing the matrix. If not provided, a
                     sequential name will be generated.

Example:
    # Create a 2x2 matrix with numeric values
    matrix_key = create_matrix([[1, 2], [3, 4]], "M")

    # Create a matrix with symbolic expressions (assuming x, y are defined)
    matrix_key = create_matrix([["x", "y"], ["x*y", "x+y"]])

Returns:
    A key for the stored matrix.
NameRequiredDescriptionDefault
matrix_dataYes
matrix_var_nameNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It usefully discloses that the matrix is stored and that a key is returned, and that an optional name defaults to a sequential generated name, but it omits error behavior, storage scope, and naming collision handling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the purpose and structured into Args, Example, and Returns sections. The example earns its place by showing symbolic expressions, though the overall text is slightly longer than strictly necessary.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given two parameters, no annotations, and an output schema, the description is complete enough for correct invocation. It covers parameter meaning and storage behavior, leaving only minor gaps around sibling-tool selection and error semantics.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It explains that matrix_data is a list of rows/columns with numeric or string expression elements, and that matrix_var_name is an optional storage name with an auto-generated fallback, covering both parameters meaningfully.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: "Creates a SymPy matrix from the provided data." It is clearly distinguishable from sibling matrix operations like matrix_inverse or matrix_determinant, though it does not explicitly name those alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied through examples showing matrix creation with numeric and symbolic entries, but there is no explicit guidance on when to use this tool versus related tools or what prerequisites must be met.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_predefined_metricC

Creates a predefined spacetime metric.

NameRequiredDescriptionDefault
metric_nameYes

Output Schema

NameRequiredDescription
resultYes

TDQS

C2.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden but only says it 'creates'. It doesn't disclose what happens on a duplicate or unknown name, whether the metric becomes active in state, or whether it mutates the session like other tools in this family.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no waste, but the brevity reflects under-specification rather than efficient communication.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values needn't be described, but for a state-mutating creation tool with zero annotations and an undocumented required parameter, the description leaves critical calling information missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% for the single parameter, so the description must compensate and doesn't. It never clarifies whether metric_name is a free-form label or must match a known predefined metric identifier.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The verb 'Creates' and resource 'predefined spacetime metric' are stated, but 'predefined' just echoes the tool name without explaining what a predefined metric actually is. It is distinguishable from create_custom_metric only by inference from the name, not from the description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No indication of when to use this versus create_custom_metric or search_predefined_metrics, no prerequisites, and no note on whether the metric must first be discovered via search. The agent must guess the workflow.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_vector_fieldA

Creates a vector field in the specified coordinate system.

Args:
    coord_sys_name: The name of the coordinate system to use.
    component_x: String expression for the x-component of the vector field.
    component_y: String expression for the y-component of the vector field.
    component_z: String expression for the z-component of the vector field.

Example:
    # First create a coordinate system
    create_coordinate_system("R")

    # Create a vector field F = (y, -x, z)
    vector_field = create_vector_field("R", "R_y", "-R_x", "R_z")

Returns:
    A key for the vector field expression.
NameRequiredDescriptionDefault
component_xYes
component_yYes
component_zYes
coord_sys_nameYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It discloses that the tool creates a vector field and returns a key, and the example shows prerequisite ordering, but it does not describe side effects, persistence, error behavior, or permissions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and then structured into Args, Example, and Returns. Given the zero schema description coverage, the parameter documentation and example each earn their place without unnecessary verbosity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value explanation is not strictly required, but the description still states that a key is returned. Parameter meanings and a prerequisite example are included, making the definition complete enough for correct invocation, though it could say more about how the returned key is used downstream.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the description compensates by explaining each parameter's meaning: coord_sys_name names the coordinate system, and component_x/y/z are string expressions for the vector components. The example further clarifies expression syntax, though constraints on valid expressions are not detailed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: it creates a vector field in a specified coordinate system. The purpose is clear, but it does not explicitly differentiate itself from sibling creation tools such as create_coordinate_system or create_custom_metric.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The example implies a prerequisite by showing create_coordinate_system first, which is useful context. However, it does not state when to use this tool versus alternatives or describe any exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

differentiate_expressionA

Differentiates an expression with respect to a variable using SymPy's diff function.

Args:
    expr_key: The key of the expression (previously introduced) to differentiate.
    var_name: The name of the variable to differentiate with respect to.
    order: The order of differentiation (default is 1 for first derivative).

Example:
    # Introduce a variable
    intro("x", [Assumption.REAL], [])

    # Create an expression to differentiate: x^3
    expr_key = introduce_expression("x**3")

    # First derivative
    first_deriv = differentiate_expression(expr_key, "x")
    # Returns 3x²

    # Second derivative
    second_deriv = differentiate_expression(expr_key, "x", 2)
    # Returns 6x

Returns:
    A key for the differentiated expression.
NameRequiredDescriptionDefault
orderNo
expr_keyYes
var_nameYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must carry the full behavioral burden. It does disclose the key-in/key-out pattern (returns a key for the new expression) and the example implies variable prerequisites, but it never says what happens if var_name was not introduced or does not appear in the expression, nor any error behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The one-line purpose is front-loaded, then Args, then a compact worked example showing first and second derivatives. The trailing Returns line duplicates the output schema and is minor waste, but overall the structure is efficient and scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need little prose, and the example plus Args are sufficient to call the tool correctly for common cases. Edge-case behavior (unknown variable, negative order) is the only meaningful gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the Args block is doing real work: it explains that expr_key refers to a previously introduced expression, that var_name is the variable of differentiation, and that order defaults to 1. It stops short of clarifying whether order must be positive or what an order of 0 yields.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence states a specific verb (differentiates) and resource (an expression with respect to a variable) and names the underlying operation (SymPy's diff), which cleanly separates it from integrate_expression, series_expansion and other calculus siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The worked example makes the prerequisite explicit: the expression must be created first via introduce_expression and the variable must exist via intro. It does not name alternatives or state when not to use it (e.g. symbolic vs numeric), so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dsolve_odeA

Solves an ordinary differential equation using SymPy's dsolve function.

Args:
    expr_key: The key of the expression (previously introduced) containing the differential equation.
    func_name: The name of the function (previously introduced) to solve for.
    hint: Optional solving method from ODEHint enum. If None, SymPy will try to determine the best method.

Example:
    # First introduce a variable and a function
    intro("x", [Assumption.REAL], [])
    introduce_function("f")

    # Create a second-order ODE: f''(x) + 9*f(x) = 0
    expr_key = introduce_expression("Derivative(f(x), x, x) + 9*f(x)")

    # Solve the ODE
    result = dsolve_ode(expr_key, "f")
    # Returns solution with sin(3*x) and cos(3*x) terms

Returns:
    A LaTeX string representing the solution. Returns an error message string if issues occur.
NameRequiredDescriptionDefault
hintNo
expr_keyYes
func_nameYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and largely meets it: it declares the return type ('LaTeX string'), the failure mode ('error message string if issues occur'), and the fallback behavior when hint is None (SymPy selects the best method). What's missing is detail on what kinds of failures produce errors or whether solution constants are included.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well-structured with Args/Example/Returns sections and the purpose front-loaded in the first line. The multi-step example is long but earns its place by showing the required setup calls; a slightly terser version would still convey the same.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a computation tool with 2 required params and established state prerequisites, the definition covers purpose, setup sequence, hint semantics, and return format with an example. An output schema exists, so return-value detail is not strictly needed, and nothing essential for a correct call appears to be missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate, and it does: expr_key is tied to a previously introduced expression, func_name to a previously introduced function, and hint is explained including the None default behavior. The 44-value ODEHint enum itself remains unexplained, leaving the agent to choose a method blindly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Solves an ordinary differential equation') and names the underlying implementation, which is unambiguous. It doesn't explicitly contrast with the PDE sibling (pdsolve_pde), so differentiation is left to the agent's inference from 'ordinary' vs 'partial'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The prerequisite workflow is spelled out clearly: an expression must already be introduced via introduce_expression and the function via introduce_function before calling. The worked example makes the intended call sequence concrete. It stops short of naming alternatives or stating when not to use it (e.g., for PDEs use pdsolve_pde).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

expand_expressionA

Expands an expression algebraically using SymPy's expand function.

Distributes products and expands integer powers of sums. Equations are expanded side by side.

Args:
    expr_key: The key of the expression (previously introduced) to expand.

Example:
    intro("x", [Assumption.REAL], [])
    expr_key = introduce_expression("(x + 1)**3")
    result_key = expand_expression(expr_key)
    # x^3 + 3x^2 + 3x + 1

Returns:
    A key for the expanded expression.
NameRequiredDescriptionDefault
expr_keyYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It does disclose useful behavior — that the result is a new key, and that equations are expanded side by side — but it never says whether the original expression is preserved or mutated, nor what happens if expr_key is unknown or the expression cannot be expanded. That is a meaningful gap for a mutation-capable algebra tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the verb and mechanism, then a compact example that demonstrates input and expected output. The Args/Returns block is slightly redundant given the output schema, and the `intro(...)` line in the example adds incidental noise, but nothing is padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter tool with an output schema, the description supplies mechanism, prerequisite, and a worked example, which is close to sufficient. The missing pieces are failure behavior and whether the source expression is left intact — details an agent would want before calling a destructive-looking transform.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the parameter, and its arg doc does explain that expr_key is the key of a previously introduced expression. That is the essential semantic (an opaque handle produced by introduce_expression) and it is stated clearly, though it doesn't describe the expected key format.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Expands an expression algebraically") and adds a concrete mechanism (SymPy expand, distribution of products, integer powers of sums). It doesn't explicitly contrast with close siblings like factor_expression, simplify_expression or series_expansion, so an agent must infer the boundary from the verb alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The example makes the call context clear: the expression must already be introduced via introduce_expression, and the "previously introduced" note in the arg doc reinforces this. It gives no explicit when-not guidance or named alternatives (e.g., use factor_expression to go the other direction), so the agent still has to reason about applicability.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

factor_expressionA

Factors a polynomial or rational expression using SymPy's factor function.

By default the factorization is over the rationals. Equations are factored side by side.

Args:
    expr_key: The key of the expression (previously introduced) to factor.
    gaussian: If True, factor over the Gaussian rationals Q(i), e.g. x**2 + 1 = (x - i)(x + i).
    modulus: Optional prime p to factor over the finite field GF(p).

Example:
    intro("x", [Assumption.REAL], [])
    expr_key = introduce_expression("x**6 - 1")
    result_key = factor_expression(expr_key)
    # (x - 1)(x + 1)(x^2 - x + 1)(x^2 + x + 1)

Returns:
    A key for the factored expression.
NameRequiredDescriptionDefault
modulusNo
expr_keyYes
gaussianNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It usefully discloses the default factorization domain, the side-by-side treatment of equations, and that the return value is a key for the factored expression. It does not cover error behavior for invalid or non-polynomial expressions, whether the tool mutates or extends state, or constraints on the modulus being prime beyond the prose 'prime p'.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first sentence states the core operation immediately, and the subsequent Args, Example, and Returns sections are well structured and free of redundancy. The example is long but earns its place by showing the key-based workflow and expected factored output.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The output schema exists, so the description need not document the exact return shape, and it appropriately says the return is a key. Given the absence of annotations, it could still say more about state effects and failure modes, but for a well-defined mathematical factoring operation it is largely complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must do all the work, and it does: expr_key is the key of a previously introduced expression; gaussian means factoring over Q(i) with a concrete example; modulus is an optional prime p for factoring over GF(p). These explanations add substantial meaning beyond the bare schema titles.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource: it factors a polynomial or rational expression, and it names the underlying SymPy operation. It is clear what the tool does, but it does not explicitly distinguish itself from related sibling tools such as expand_expression, cancel_expression, or apart_expression.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains the default domain (rationals) and the two alternative domains (Gaussian rationals and finite fields), which implies when the optional parameters matter. However, it never states when to choose factor_expression over related symbolic-manipulation siblings, nor does it give exclusions or prerequisites beyond noting that expr_key must have been previously introduced.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

integrate_expressionA

Integrates an expression with respect to a variable using SymPy's integrate function.

Args:
    expr_key: The key of the expression (previously introduced) to integrate.
    var_name: The name of the variable to integrate with respect to.
    lower_bound: Optional lower bound for definite integration.
    upper_bound: Optional upper bound for definite integration.

Example:
    # Introduce a variable
    intro("x", [Assumption.REAL], [])

    # Create an expression to integrate: x^2
    expr_key = introduce_expression("x**2")

    # Indefinite integration
    indefinite_result = integrate_expression(expr_key, "x")
    # Returns x³/3

    # Definite integration from 0 to 1
    definite_result = integrate_expression(expr_key, "x", "0", "1")
    # Returns 1/3

Returns:
    A key for the integrated expression.
NameRequiredDescriptionDefault
expr_keyYes
var_nameYes
lower_boundNo
upper_boundNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It does disclose the return form ('A key for the integrated expression') and demonstrates concrete outputs, but it never states that a new expression key is registered into state, nor what happens on an invalid or unknown expr_key, nor how symbolic vs numeric bounds behave.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in sentence one, followed by a structured Args/Example/Returns layout. The example is somewhat long but each line demonstrates a distinct call pattern (indefinite vs definite), so it largely earns its space.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be spelled out, yet the description still gives the agent the key semantic. Combined with full argument documentation and a runnable example, the definition is nearly complete; only error behavior and state side effects are absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must document all four parameters, and the Args block does so including that bounds are optional and gate definite integration. The example clarifies that bounds are passed as strings ('0', '1'), but it does not say whether symbolic or unbounded-free-form bounds are accepted.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence states a specific verb and resource ('Integrates an expression with respect to a variable') and names the underlying engine (SymPy's integrate). It is clearly distinguishable from the differentiation, simplification and limit siblings without any schema inspection.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The worked example makes the selection rule explicit: omit bounds for indefinite integration, supply both for definite integration over 0 to 1. It does not name alternatives such as differentiate_expression or explain when-not to use this tool, so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

introC

Introduces a sympy variable with specified assumptions and stores it.

Takes a variable name and a list of positive and negative assumptions.

NameRequiredDescriptionDefault
var_nameYes
neg_assumptionsYes
pos_assumptionsYes

Output Schema

NameRequiredDescription
resultYes

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. 'Stores it' hints at session mutation, but nothing is said about redeclaring an existing name, conflicting assumptions, error behavior, or whether state persists across calls — all material for a stateful tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with the core action front-loaded and no filler. The second sentence mostly restates the parameter names, so it earns only partial keep.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Although an output schema exists, the description leaves three required, zero-documented parameters unexplained and says nothing about the session-state side effect. For a stateful 3-param tool with no annotations, this is under-specified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate and largely doesn't. It maps loosely onto var_name/pos_assumptions/neg_assumptions but never explains the semantics of the two lists (e.g. one declares True assumptions, the other declares False) or how the enum values are chosen.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Introduces a sympy variable') and adds that the variable is stored, which conveys the stateful effect. It does not differentiate from the close sibling intro_many or from introduce_expression/introduce_function, so an agent must still infer which of the four to pick.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this versus intro_many (bulk), introduce_expression, or introduce_function, and no mention of prerequisites such as a required prior reset_state. Usage is only implicit in the fact that it takes a variable name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

introduce_expressionA

Parses a sympy expression string using available local variables and stores it. Assigns it to either a temporary name (expr_0, expr_1, etc.) or a user-specified global name.

Uses Sympy parse_expr to parse the expression string.

Applies default Sympy canonicalization rules unless canonicalize is False.

For equations (x^2 = 1) make the input string "Eq(x^2, 1") not "x^2 == 1"

Examples:

    {expr_str: "Eq(x^2 + y^2, 1)"}
    {expr_str: "Matrix(((25, 15, -5), (15, 18, 0), (-5, 0, 11)))"}
    {expr_str: "pi+e", "expr_var_name": "z"}
NameRequiredDescriptionDefault
expr_strYes
canonicalizeNo
expr_var_nameNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden well: it discloses the parsing engine (parse_expr), default canonicalization behavior and how to disable it, and the naming convention (temporary expr_N vs. a global name). It omits failure behavior for undefined variables and what happens on a name collision, which keeps it short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then the equation-syntax caveat, then examples — good ordering. The sentence 'Uses Sympy parse_expr to parse the expression string' largely restates the first sentence, and the equation example has a mismatched quote, so it is not airtight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the description covers the pieces an agent actually needs: input syntax, equation form, naming, and canonicalization. The main remaining gap is the absence of any routing guidance against the many sibling expression tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate, and it largely does: expr_str is explained with equation syntax guidance plus three concrete examples, canonicalize is described as a default-on behavior, and expr_var_name is described as an optional global name overriding temp naming. What 'canonicalize' actually does to the expression remains vague.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: parses a sympy expression string from local variables and stores it under a generated (expr_0) or user-supplied name. That is clear enough to separate it from computational siblings like simplify_expression or introduce_function, though it never explicitly names those alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied — an agent can infer this is the entry point for bringing an expression into the session before applying simplify/integrate/differentiate. There is no explicit statement of when to prefer this over introduce_function, nor any prerequisites or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

introduce_functionA

Introduces a SymPy function variable and stores it.

Takes a function name and creates a SymPy Function object for use in defining differential equations.

Example:
    {func_name: "f"} will create the function f(x), f(t), etc. that can be used in expressions

Returns:
    The name of the created function.
NameRequiredDescriptionDefault
func_nameYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and discloses key behavior: it creates and stores a SymPy Function object, which is a state-changing operation. It also explains the return value, though it omits edge cases like overwriting an existing function name.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded and appropriately sized, with the core purpose stated first, followed by a helpful example. The explicit Returns section is somewhat redundant because an output schema exists, but it does not detract significantly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the low complexity (one parameter) and the presence of an output schema, the description is nearly complete: it covers purpose, usage context, an example, and return behavior. It could be improved by mentioning sibling alternatives, but nothing essential for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. The example {func_name: "f"} clarifies that the parameter is a bare function name and that the resulting function can take arbitrary arguments like x or t, adding meaningful semantics beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Introduces a SymPy function variable' and 'creates a SymPy Function object'. It is clear what the tool does, but it does not explicitly distinguish itself from sibling tools like introduce_expression or intro.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives implied usage context ('for use in defining differential equations'), but it does not state when to use this tool instead of alternatives such as introduce_expression or dsolve_ode. No explicit exclusions or alternatives are provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

intro_manyA

Introduces multiple sympy variables with specified assumptions and stores them.

Takes a list of VariableDefinition objects for the 'variables' parameter.
Each object in the list specifies:
- var_name: The name of the variable (string).
- pos_assumptions: A list of positive assumption strings (e.g., ["real", "positive"]).
- neg_assumptions: A list of negative assumption strings (e.g., ["complex"]).

The JSON payload for the 'variables' argument should be a direct list of these objects, for example:
```json
[
    {
        "var_name": "x",
        "pos_assumptions": ["real", "positive"],
        "neg_assumptions": ["complex"]
    },
    {
        "var_name": "y",
        "pos_assumptions": [],
        "neg_assumptions": ["commutative"]
    }
]
```

The assumptions must be consistent, so a real number is not allowed to be non-commutative.

Prefer this over intro() for multiple variables because it's more efficient.
NameRequiredDescriptionDefault
variablesYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It discloses that variables are stored and that assumptions must be consistent, which adds useful context beyond the schema, but it does not say what happens with duplicate variable names, conflicting existing assumptions, or failed validation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core action and then expands into the nested parameter shape, which is justified by the zero schema description coverage. The JSON example is somewhat repetitive after the bullet explanations, but it is useful for correct invocation and not excessive.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The output schema exists, so return values need not be explained. The description covers the nested input shape well and states the key consistency constraint, though it leaves some mutation behavior unclear, such as overwrite semantics for existing variables.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must fully explain the parameter. It does this thoroughly by describing the `variables` list, each `VariableDefinition` field, the meaning of positive and negative assumption strings, and a complete JSON example.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: it introduces multiple sympy variables with specified assumptions and stores them. It also explicitly distinguishes itself from the sibling `intro()` by saying it should be preferred for multiple variables, so an agent can select it without confusion.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an explicit alternative: `intro()` should be used for single variables, while this tool should be preferred for multiple variables because it is more efficient. This is exactly the when-to-use guidance an agent needs for selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

limit_expressionA

Computes the limit of an expression as a variable tends to a point, using SymPy's limit.

Args:
    expr_key: The key of the expression (previously introduced).
    var_name: The variable (previously introduced) that tends to the point.
    point: The limit point, e.g. "0", "1/2", "pi/2", "oo" (+infinity), "-oo".
        Parsed without eval: only numbers, introduced variables, oo/inf/pi/E/I,
        arithmetic operators and sqrt/exp/log/sin/cos/tan/Rational are accepted.
    direction: "+-" for the two-sided limit (default), "+" from the right, "-" from the left.
        Ignored for limits at +oo or -oo.

Example:
    intro("x", [Assumption.REAL], [])
    expr_key = introduce_expression("sin(x)/x")
    result_key = limit_expression(expr_key, "x", "0")
    # 1
    expr_key = introduce_expression("(1 + 1/x)**x")
    result_key = limit_expression(expr_key, "x", "oo")
    # e

Returns:
    A key for the limit. Returns an error message if the limit does not exist
    (one-sided limits differ, or the expression oscillates).
NameRequiredDescriptionDefault
pointYes
expr_keyYes
var_nameYes
directionNo+-

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so well: it discloses the no-eval parsing restriction and the exact whitelist of accepted token types, the direction default of '+-' and that direction is ignored at ±oo, and the error behavior when a limit does not exist (differing one-sided limits or oscillation). These are non-obvious traits an agent could not infer from the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded one-sentence purpose followed by Args/Example/Returns in a predictable order, with no filler prose. The second worked example is valuable, though the example's trailing '# 1' and '# e' comment results slightly overlap what the Returns section already covers.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a four-parameter symbolic tool with an output schema and zero schema description coverage, the description supplies the missing prerequisites, point-syntax constraints, direction semantics, and failure mode. An agent has everything needed to invoke it correctly and interpret a returned key versus an error message.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate and it does: all four parameters are explained, including the accepted syntax for 'point' ("0", "1/2", "pi/2", "oo", "-oo" plus operators and functions) and the meaning plus default of the direction enum. This adds substantial meaning beyond bare title/type fields.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and mathematical resource: computes the limit of an expression as a variable tends to a point, via SymPy's limit. The domain term 'limit' is unambiguous against siblings like integrate_expression or series_expansion, though the description never explicitly names an alternative to route away from.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The Args section establishes the prerequisite that expr_key and var_name must have been 'previously introduced', which tells the agent this tool is not a first step. The worked example further anchors the intended call sequence (intro → introduce_expression → limit_expression). No explicit when-not-use guidance is given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

matrix_determinantB

Calculates the determinant of a matrix using SymPy's det method.

Args:
    matrix_key: The key of the matrix to calculate the determinant for.

Example:
    # Create a matrix
    matrix_key = create_matrix([[1, 2], [3, 4]])

    # Calculate its determinant
    det_key = matrix_determinant(matrix_key)
    # Results in -2

Returns:
    A key for the determinant expression.
NameRequiredDescriptionDefault
matrix_keyYes

Output Schema

NameRequiredDescription
resultYes

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description bears full behavioral burden. It discloses that it uses SymPy's det and returns a key, but omits critical behavior: whether the matrix must be square, what happens on error, and whether the operation is pure/side-effect free.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well-structured with Args, Example, and Returns sections; the purpose is front-loaded. The example earns its place by demonstrating the create-then-determinant workflow, though it adds length.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value explanation is technically unnecessary (though provided). The main completeness gap is the absence of any note about square matrices or error behavior for a computation with no annotations to fall back on.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema coverage on the single parameter, the description compensates well by explaining that matrix_key is 'the key of the matrix' and the example clarifies it comes from create_matrix. The key-reference semantics are made clear beyond the bare string type.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Calculates the determinant of a matrix.' An agent can distinguish this from matrix_inverse or matrix_eigenvalues by purpose alone, though the description does not explicitly contrast with those siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The example shows how to call the tool but gives no guidance on when to use it versus alternatives or what conditions must hold (e.g., square matrix). No when/when-not context is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

matrix_eigenvaluesA

Calculates the eigenvalues of a matrix using SymPy's eigenvals method.

Args:
    matrix_key: The key of the matrix to calculate eigenvalues for.

Example:
    # Create a matrix
    matrix_key = create_matrix([[1, 2], [2, 1]])

    # Calculate its eigenvalues
    evals_key = matrix_eigenvalues(matrix_key)

Returns:
    A key for the eigenvalues expression (usually a dictionary mapping eigenvalues to their multiplicities).
NameRequiredDescriptionDefault
matrix_keyYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so the description carries the full behavioral burden. It does disclose the key-based state pattern and that the result is 'usually a dictionary mapping eigenvalues to their multiplicities', which is genuinely informative. It omits whether computation is exact/symbolic vs numeric, behavior on non-diagonalizable or non-square matrices, and cost on large matrices.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded in the first sentence, followed by a compact Args/Example/Returns block that is scannable. The example is short and directly reinforces the argument semantics, so the length is justified, though the Returns section partly duplicates the output schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter, non-destructive computation tool with an output schema present, the description covers purpose, argument meaning, invocation example, and result shape. Missing only edge-case behavior (non-square input, symbolic results), which keeps it from a 5.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate, and it does: 'matrix_key: The key of the matrix' clarifies that the argument is a handle to a previously created matrix rather than a raw matrix literal, and the example shows exactly how such a key is produced. That is the key semantic an agent could otherwise get wrong.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence names a specific verb and resource ('Calculates the eigenvalues of a matrix') and even names the underlying method (SymPy eigenvals), which makes it distinguishable from matrix_eigenvectors and matrix_determinant by name alone. It stops short of explicitly contrasting itself with those siblings, so it is clear but not fully differentiated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The worked example implicitly tells the agent the precondition (a matrix key must first come from create_matrix), which is useful workflow guidance. However, there is no explicit statement of when to use this versus matrix_eigenvectors, matrix_determinant, or matrix_inverse, and no exclusions or failure conditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

matrix_eigenvectorsA

Calculates the eigenvectors of a matrix using SymPy's eigenvects method.

Args:
    matrix_key: The key of the matrix to calculate eigenvectors for.

Example:
    # Create a matrix
    matrix_key = create_matrix([[1, 2], [2, 1]])

    # Calculate its eigenvectors
    evecs_key = matrix_eigenvectors(matrix_key)

Returns:
    A key for the eigenvectors expression (usually a list of tuples (eigenvalue, multiplicity, [eigenvectors])).
NameRequiredDescriptionDefault
matrix_keyYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must carry the behavioral burden. It discloses the method used and the return format (a key for the eigenvectors expression), which is useful. It does not state whether the operation is read-only or stateful, nor does it describe error conditions or constraints like square-matrix requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded in the first sentence, followed by structured Args, Example, and Returns sections. Each section adds value, though the example is somewhat verbose for a one-parameter tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simple one-parameter schema, output schema availability, and lack of annotations, the description is largely complete: it explains what the tool does, how to supply the input key, and what the return key represents. Minor gaps remain around matrix constraints and state behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It does: 'matrix_key: The key of the matrix to calculate eigenvectors for' adds clear meaning beyond the bare schema title, and the example demonstrates obtaining a key via create_matrix. It does not specify format details or square-matrix constraints, so not a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Calculates') and resource ('eigenvectors of a matrix') and names the underlying SymPy method. It is clearly distinct from matrix_eigenvalues by resource name, but does not explicitly say when to use this instead of eigenvalue calculation, so sibling differentiation is only implicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The example implies a workflow (create_matrix then matrix_eigenvectors), which provides some usage context. However, there is no explicit when-to-use guidance, no alternatives mentioned (e.g., matrix_eigenvalues), and no prerequisites such as the matrix being square.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

matrix_inverseA

Calculates the inverse of a matrix using SymPy's inv method.

Args:
    matrix_key: The key of the matrix to invert.

Example:
    # Create a matrix
    matrix_key = create_matrix([[1, 2], [3, 4]])

    # Calculate its inverse
    inv_key = matrix_inverse(matrix_key)

Returns:
    A key for the inverted matrix.
NameRequiredDescriptionDefault
matrix_keyYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It does disclose the backend method (SymPy inv) and what is returned (a key for the inverted matrix), but it says nothing about error behavior for singular matrices or whether the original matrix is mutated. Adequate but with clear gaps for a zero-annotation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The one-line purpose is front-loaded and every section (Args, Example, Returns) is short and scannable. The example is slightly more verbose than strictly needed but demonstrates the key-passing pattern usefully.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With only one parameter and an output schema present, the description needn't explain return shape further, and the purpose, input origin, and workflow are all covered. The remaining miss is failure semantics for non-invertible input, which an agent would want to know before calling.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate, and it largely does: it explains that matrix_key is the key of the matrix to invert and the example shows it originating from create_matrix. The only remaining gap is validation/format detail (e.g., whether a stale or unknown key produces an error).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Calculates the inverse of a matrix') plus the underlying method (SymPy's inv). This is unambiguously distinct from siblings like matrix_determinant, matrix_eigenvalues, and create_matrix.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The example implies the prerequisite workflow (create_matrix then matrix_inverse) and the Args note that a matrix key is required, which gives some context for when to call it. However, there is no explicit when-not guidance, and nothing about singular/non-invertible matrices where this tool would fail or be inappropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

pdsolve_pdeA

Solves a partial differential equation using SymPy's pdsolve function.

Args:
    expr_key: The key of the expression (previously introduced) containing the PDE.
             If the expression is not an equation (Eq), it will be interpreted as
             PDE = 0.
    func_name: The name of the function (previously introduced) to solve for.
               This should be a function of multiple variables.

Example:
    # First introduce variables and a function
    intro("x", [Assumption.REAL], [])
    intro("y", [Assumption.REAL], [])
    introduce_function("f")

    # Create a PDE: 1 + 2*(ux/u) + 3*(uy/u) = 0
    expr_key = introduce_expression(
        "Eq(1 + 2*Derivative(f(x, y), x)/f(x, y) + 3*Derivative(f(x, y), y)/f(x, y), 0)"
    )

    # Solve the PDE
    result = pdsolve_pde(expr_key, "f")
    # Returns solution with exponential terms and arbitrary function

Returns:
    A LaTeX string representing the solution. Returns an error message string if issues occur.
NameRequiredDescriptionDefault
hintNo
expr_keyYes
func_nameYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does add real value: it explains that a non-Eq expression is treated as PDE = 0 and that failures surface as an error-message string rather than an exception. It says nothing about side effects (e.g., whether the solution is registered as a new expression key in session state), performance limits, or which PDE classes pdsolve can actually handle.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in the opening sentence, followed by Args, a concrete Example, and Returns. The example is longer than strictly necessary but earns its space by demonstrating the prerequisite call sequence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so the Returns note is supplementary, and the Args plus example cover the required parameters well. The unresolved gap is the undocumented 'hint' enum and the absence of any statement about state side effects, which an agent needs before calling a stateful computer-algebra tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% (titles only), so the description must compensate. It does explain expr_key (key of a previously introduced expression, non-Eq treated as = 0) and func_name (a previously introduced function of multiple variables), but the optional 'hint' parameter — an enum of four PDE model types — is never mentioned anywhere, leaving one third of the parameters opaque.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence gives a specific verb and resource ('Solves a partial differential equation using SymPy's pdsolve') that is clearly distinct from dsolve_ode and the algebra/calculus siblings. It does not explicitly name the ODE counterpart as an alternative, so it stops short of full sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The worked example implicitly spells out the required precondition chain: variables and the function must be introduced with intro/introduce_function before introduce_expression creates the PDE key. That gives clear usage context, but there is no explicit 'use this instead of X' routing against dsolve_ode or a statement of when pdsolve will fail.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

quantity_simplify_unitsB

Simplifies a quantity with units using sympy's built-in simplify method for Quantity objects.

Args:
    expr_key: The key of the expression (previously introduced) to simplify.
    unit_system: Optional unit system (from UnitSystem enum). Not used with direct simplify method.

The following units are available by default:
    SI base units: meter, second, kilogram, ampere, kelvin, mole, candela
    Length: kilometer, millimeter
    Mass: gram
    Energy: joule
    Force: newton
    Pressure: pascal
    Power: watt
    Electric: coulomb, volt, ohm, farad, henry
    Constants: speed_of_light, gravitational_constant, planck

Example:
    # Simplify force expressed in base units
    expr_key = introduce_expression("kilogram*meter/second**2")
    result = quantity_simplify_units(expr_key)
    # Returns newton (as N = kg·m/s²)

    # Simplify a complex expression with mixed units
    expr_key = introduce_expression("joule/(kilogram*meter**2/second**2)")
    result = quantity_simplify_units(expr_key)
    # Returns a dimensionless quantity (1)

    # Simplify electrical power expression
    expr_key = introduce_expression("volt*ampere")
    result = quantity_simplify_units(expr_key)
    # Returns watt

Example with Speed of Light:
    # Introduce the speed of light
    c_key = introduce_expression("speed_of_light")

    # Convert to kilometers per hour
    km_per_hour_key = convert_to_units(c_key, ["kilometer", "1/hour"])

    # Simplify to get the numerical value
    simplified_key = quantity_simplify_units(km_per_hour_key)

    # Print the result
    print_latex_expression(simplified_key)
    # Shows the numeric value of speed of light in km/h

Returns:
    A key for the simplified expression, or an error message.
NameRequiredDescriptionDefault
expr_keyYes
unit_systemNo

Output Schema

NameRequiredDescription
resultYes

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must carry the full behavioral burden. It does disclose that a new expression key is returned and that an 'error message' can result, and the examples reveal that simplification normalizes to derived SI units rather than merely tidying syntax. It does not state whether a new expression is registered in state, nor clarify the practical effect of the unit_system parameter beyond saying it is 'not used'.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded, which is good, but the body is bloated: a 20-line unit inventory plus four multi-line commented examples, when two examples would establish the same behavior. The trailing 'Returns' line also restates what the output schema already declares, so not every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the description still supplies an available-units inventory and worked examples that make the tool callable without guesswork. Remaining gaps are its relationship to sibling simplification/conversion tools and the precise semantics of unit_system.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description has to compensate; it does explain both parameters in the Args block, noting expr_key must be 'previously introduced' and unit_system comes from the UnitSystem enum. However, the five enum values (MKS, MKSA, natural, SI, cgs) are never explained and the note that unit_system is 'Not used with direct simplify method' is ambiguous about whether passing it has any effect.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence gives a specific verb and resource ('Simplifies a quantity with units') and the examples concretely show the outcome (kg·m/s² → newton, volt·ampere → watt), which tells an agent what the tool actually produces. It never names or contrasts with the obvious siblings simplify_expression and convert_to_units, so differentiation is left to inference.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied through the 'Example with Speed of Light' chain, which shows convert_to_units followed by quantity_simplify_units, so an agent can infer the intended workflow. There is no explicit statement of when to prefer this over convert_to_units or simplify_expression, and no when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

reset_stateA

Resets the state of the SymPy MCP server.

Clears all stored variables, functions, expressions, metrics, tensors,
coordinate systems, and resets the expression counter.

Then reinitializes unit variables.

Runs after all tool calls for a given computation are done to reset the state for the next computation.

Returns:
    A message confirming the reset.
NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full disclosure burden and does well: it lists everything that gets destroyed and notes the side effect that unit variables are reinitialized plus the expression counter reset. It stops short of stating irreversibility or that any unsaved work is lost, but the destructive scope is well conveyed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and the cleared-items list, all in efficient sentences. The 'Returns:' block is somewhat redundant given an output schema exists, but it does not bloat the definition meaningfully.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

A zero-parameter tool with an output schema, so return-value explanation is unnecessary. The description covers what is destroyed, the side effects, and when to call it. Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Zero parameters, so the baseline is 4; there is nothing for the description to document. No input is required or accepted.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (resets) and resource (SymPy MCP server state) and enumerates exactly what is cleared (variables, functions, expressions, metrics, tensors, coordinate systems, expression counter). No sibling tool does state reset, so the agent can immediately distinguish it from all the compute/introduce tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says to run it after all tool calls for a given computation are done, to reset for the next computation. This gives clear context for when to invoke it. No alternative reset tool exists to mention, so there is nothing left to disambiguate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_predefined_metricsC

Searches for predefined metrics in einsteinpy.symbolic.predefined.

NameRequiredDescriptionDefault
queryYes

Output Schema

NameRequiredDescription
resultYes

TDQS

C2.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It does not disclose matching semantics (exact, substring, case sensitivity), whether an empty query returns everything, or any limits on results. Only the fact that it is a read/search operation can be inferred from the verb.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is a single front-loaded sentence with no filler, which is good. But the brevity comes at the cost of under-specification rather than efficiency, so it does not earn a high conciseness score.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value shape need not be described. Still, for a search tool with zero annotation coverage and an entirely undocumented query parameter, the description omits information an agent needs to invoke it correctly (matching rules, result limits).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must explain the single 'query' parameter. It never says what the query is matched against (metric name, description, keywords) or what format it expects, leaving the only required parameter undocumented in both places.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a verb (searches) and resource (predefined metrics), and scopes it to the einsteinpy.symbolic.predefined module, which does separate it from the create_predefined_metric sibling. However, it never explains what a 'predefined metric' is or what aspect of it the query matches, so the purpose is only minimally clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this versus create_predefined_metric or create_custom_metric, no mention of prerequisites, and no statement of what a search returns when nothing matches. The agent must infer usage entirely from the tool name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

series_expansionA

Computes a Taylor/Laurent/Puiseux expansion (développement limité) using SymPy's series.

Args:
    expr_key: The key of the expression (previously introduced) to expand.
    var_name: The variable (previously introduced) of the expansion.
    point: The expansion point, e.g. "0", "1", "pi/2", "oo". Parsed without eval
        with the same rules as limit_expression. Defaults to "0".
    order: Terms up to (var - point)**(order - 1) are kept, followed by O((var - point)**order).
        Must be between 1 and 50. Defaults to 6.
    remove_order_term: If True, drop the O(...) remainder and return the truncated polynomial.

Example:
    intro("x", [Assumption.REAL], [])
    expr_key = introduce_expression("exp(x)")
    result_key = series_expansion(expr_key, "x", "0", 4)
    # 1 + x + x^2/2 + x^3/6 + O(x^4)

Returns:
    A key for the expansion.
NameRequiredDescriptionDefault
orderNo
pointNo0
expr_keyYes
var_nameYes
remove_order_termNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses defaults (point='0', order=6), the hard bound 1–50 on order, that point is parsed without eval, exactly which terms are kept and which O(...) term is appended, and that remove_order_term truncates. It does not say how out-of-range order or unknown keys fail, which is the main remaining gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first sentence front-loads what the tool does, followed by structured Args/Example/Returns blocks with no filler. The worked example is long but earns its place by demonstrating the key-chaining convention; the Returns section is slightly thin relative to the rest.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 5-parameter symbolic tool with a stateful key convention, the description covers inputs, defaults, truncation semantics, and the example end-to-end. Since an output schema exists, the brief 'Returns: a key' note suffices; only error/failure behavior is left unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate, and it does: every parameter is explained, including the non-obvious semantics of order ('terms up to (var - point)**(order - 1) are kept'), accepted point formats with examples, and the effect of remove_order_term. This is meaningfully richer than the bare schema types.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: computes a Taylor/Laurent/Puiseux expansion (développement limité) via SymPy's series. The parenthetical synonym and named algorithm make it unambiguous versus siblings like limit_expression or expand_expression.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The example workflow makes preconditions explicit: the variable must be introduced via intro() and the expression via introduce_expression() before calling, and point parsing is stated to follow limit_expression's rules. It stops short of saying when to prefer this over limit_expression or which sibling handles non-series approximations.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

simplify_expressionA

Simplifies a mathematical expression using SymPy's simplify function.

Args:
    expr_key: The key of the expression (previously introduced) to simplify.

Example:
    # Introduce variables
    intro("x", [Assumption.REAL], [])
    intro("y", [Assumption.REAL], [])

    # Create an expression to simplify: sin(x)^2 + cos(x)^2
    expr_key = introduce_expression("sin(x)**2 + cos(x)**2")

    # Simplify the expression
    simplified = simplify_expression(expr_key)
    # Returns 1

Returns:
    A key for the simplified expression.
NameRequiredDescriptionDefault
expr_keyYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does reasonably well: it discloses the underlying algorithm (SymPy simplify), the precondition that the expression must already exist, and that the result is a new key rather than a mutation. It omits failure modes (e.g. invalid or stale expr_key) and whether the original expression remains queryable.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in the first sentence, with args, a concrete example and returns following in a predictable structure. The example is longer than strictly necessary but earns its place by showing the key-based data flow that the schema does not convey.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value documentation is a bonus rather than a requirement, and the description still states a key is returned plus a concrete example (sin^2+cos^2 returns 1). The only real gap for a single-parameter, pure-computation tool is the absence of any error or edge-case note.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate, and it does: expr_key is explained as the key of a previously introduced expression, which is meaningfully more than the bare 'Expr Key' schema title. The worked example further illustrates the value format produced by introduce_expression.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence gives a specific verb and resource ('Simplifies a mathematical expression') and names the underlying engine (SymPy's simplify). It does not differentiate itself from close siblings such as factor_expression, expand_expression, cancel_expression or apart_expression, so an agent must infer the distinction from names alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the worked example, which shows introducing variables, creating an expression, then simplifying it. However, there is no explicit when-to-use/when-not-to-use guidance relative to the many other expression-rewriting siblings, and no statement of prerequisites beyond 'previously introduced'.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

solve_algebraicallyA

Solves an equation (expression = 0) algebraically for a given variable.

Args:
    expr_key: The key of the expression (previously introduced) to be solved.
    solve_for_var_name: The name of the variable (previously introduced) to solve for.
    domain: The domain to solve in: Domain.COMPLEX, Domain.REAL, Domain.INTEGERS, or Domain.NATURALS. Defaults to Domain.COMPLEX.

Returns:
    A LaTeX string representing the set of solutions. Returns an error message string if issues occur.
NameRequiredDescriptionDefault
domainNocomplex
expr_keyYes
solve_for_var_nameYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden and usefully discloses the prerequisite that expr_key and solve_for_var_name refer to previously introduced objects. It also states that the return value is a LaTeX string for the solution set or an error message string; it does not explicitly discuss side effects or mutation, but the solver nature and return behavior are clear.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core action, then uses clear Args and Returns sections. Every sentence adds necessary information, and there is no redundant restatement of the tool name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a three-parameter algebraic solver with an output schema, the description covers the core semantics, parameter meanings, domain options, default, and return type. It is nearly complete, though it could further clarify how this differs from system-solving or inequality-solving siblings.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate fully, and it does: all three parameters are explained. It clarifies that expr_key and solve_for_var_name refer to previously introduced objects, lists the domain choices, and states the default Domain.COMPLEX.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: solves an equation, explicitly defined as expression = 0, algebraically for a given variable. This distinguishes it from siblings such as solve_inequality and the system solvers, which handle inequalities or multiple equations rather than a single algebraic equation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when the tool is applicable by specifying that it solves expression = 0 for a variable. However, it does not explicitly say when to use this rather than solve_linear_system, solve_nonlinear_system, or other alternatives, nor does it state exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

solve_inequalityA

Solves an inequality in one real variable using SymPy's solveset over the reals.

The inequality is introduced with introduce_expression, e.g. "x**2 - 1 > 0",
"(x - 1)/(x + 2) <= 0", or a combination "And(x > 0, x**2 < 4)" / "Or(...)".
For a double inequality a < f(x) < b use "And(a < f(x), f(x) < b)".

Args:
    expr_key: The key of the inequality (previously introduced).
    var_name: The variable (previously introduced) to solve for.

Example:
    intro("x", [Assumption.REAL], [])
    expr_key = introduce_expression("x**2 - 1 > 0")
    solve_inequality(expr_key, "x")
    # \left(-\infty, -1\right) \cup \left(1, \infty\right)

Returns:
    A LaTeX string representing the solution set. Returns an error message string if issues occur.
NameRequiredDescriptionDefault
expr_keyYes
var_nameYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It discloses that solving is over the reals via solveset, that the result is a LaTeX string, and that errors return a message string; it does not explicitly state read-only behavior or what happens if the expression or variable was not introduced.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the purpose, then structured with Args, Example, and Returns sections. Each part adds useful information for correct invocation without unnecessary repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the lack of annotations, 0% schema description coverage, and an output schema, the description is complete enough: it explains prerequisites, both parameters, inequality encoding including double inequalities, an example, return format, and error behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must explain both parameters. It defines expr_key as the key of a previously introduced inequality and var_name as the previously introduced variable to solve for, and the example demonstrates their use.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: solve an inequality in one real variable using SymPy's solveset over the reals. It is clear what the tool does, but it does not explicitly distinguish itself from sibling tools such as solve_algebraically.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear prerequisite context: the inequality must first be introduced with introduce_expression, and double inequalities must be encoded with And. It does not state when to use this tool versus alternatives like solve_algebraically or solve_nonlinear_system, so it lacks explicit exclusions or alternative routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

solve_linear_systemA

Solves a system of linear equations using SymPy's linsolve.

Args:
    expr_keys: The keys of the expressions (previously introduced) forming the system.
    var_names: The names of the variables to solve for.
    domain: The domain to solve in (Domain.COMPLEX, Domain.REAL, etc.). Defaults to Domain.COMPLEX.

Returns:
    A LaTeX string representing the solution set. Returns an error message string if issues occur.
NameRequiredDescriptionDefault
domainNocomplex
expr_keysYes
var_namesYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it does disclose the return format (LaTeX solution set) and error behavior (error message string on failure). However, it does not describe what happens for inconsistent or underdetermined systems, nor does it state prerequisites or permissions, leaving meaningful behavioral gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action in the first sentence, followed by a conventional Args/Returns block. Every line is informative; minor redundancy in restating the default that also appears in the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a three-parameter solver with an output schema available, the description covers purpose, parameters, and return type adequately. Remaining gaps concern edge-case behavior for singular systems, which is minor given the output schema and error-message disclosure.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate, and it does: each of the three parameters is explained, including that domain defaults to Domain.COMPLEX. It still does not clarify format expectations for expr_keys/var_names (e.g. whether keys are opaque handles vs. strings of expressions), which the bare schema leaves ambiguous.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Solves a system of linear equations') and names the underlying mechanism (SymPy's linsolve), which implicitly distinguishes it from solve_nonlinear_system and solve_inequality. It does not explicitly name the siblings it supersedes, so differentiation is inferential rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The word 'linear' implies when this tool applies versus nonlinear solvers, and 'previously introduced' hints at a prerequisite, but there is no explicit when-to-use/when-not guidance or named alternative such as solve_algebraically. Usage is implied rather than directed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

solve_nonlinear_systemA

Solves a system of nonlinear equations using SymPy's nonlinsolve.

Args:
    expr_keys: The keys of the expressions (previously introduced) forming the system.
    var_names: The names of the variables to solve for.
    domain: The domain to solve in (Domain.COMPLEX, Domain.REAL, etc.). Defaults to Domain.COMPLEX.

Returns:
    A LaTeX string representing the solution set. Returns an error message string if issues occur.
NameRequiredDescriptionDefault
domainNocomplex
expr_keysYes
var_namesYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It does usefully disclose that the return is a LaTeX solution set and that failures come back as an error message string rather than an exception, but it says nothing about solving behavior such as solution completeness, multiplicity, or possible non-termination on hard systems.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded one-line purpose followed by compact Args/Returns blocks; every line carries information. Slightly verbose in restating the default already encoded in the schema, but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

All three parameters are explained and the return behavior is described, which is more than needed since an output schema exists. The main gap is behavioral context for a solver with no annotations, such as what happens with underdetermined or inconsistent systems beyond a generic error string.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate, and it does: expr_keys is clarified as keys of previously introduced expressions, var_names as the solve targets, and domain as the solution domain with its default. It adds real meaning beyond the bare schema for all three parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Solves a system of nonlinear equations using SymPy's nonlinsolve'), and the word 'nonlinear' implicitly separates it from the sibling solve_linear_system. It does not name that sibling explicitly, so differentiation is inferable rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: an agent can infer it should be used for nonlinear systems, but the description never says when to prefer it over solve_algebraically or solve_linear_system, nor any prerequisites. No when-not-to-use guidance is present.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

substitute_expressionA

Substitutes a variable in an expression with another expression using SymPy's subs method.

Args:
    expr_key: The key of the expression to perform substitution on.
    var_name: The name of the variable to substitute.
    replacement_expr_key: The key of the expression to substitute in place of the variable.

Example:
    # Create variables x and y
    intro("x", [], [])
    intro("y", [], [])

    # Create expressions
    expr1 = introduce_expression("x**2 + y**2")
    expr2 = introduce_expression("sin(x)")

    # Substitute y with sin(x) in x^2 + y^2
    result = substitute_expression(expr1, "y", expr2)
    # Results in x^2 + sin^2(x)

Returns:
    A key for the resulting expression after substitution.
NameRequiredDescriptionDefault
expr_keyYes
var_nameYes
replacement_expr_keyYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It does disclose that the operation is non-destructive to inputs (a new key is returned) and names the underlying SymPy subs semantics, but it says nothing about error behavior for unknown keys, a variable absent from the expression, or any state/lifecycle effects on the expression registry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the one-sentence purpose, then Args, then a compact runnable example, then Returns. Each block adds distinct information and the example is short enough to earn its space.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the return value needn't be explained in depth, and the description still states it returns a key. Three required params are fully documented. The remaining gap is failure modes and whether expression keys persist or are consumed by the operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% — properties carry only titles — so the Args block is the sole documentation. It correctly clarifies the important asymmetry that expr_key and replacement_expr_key are registry keys while var_name is a plain variable name, and the example reinforces that distinction concretely.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence names a specific verb and resource — substituting a variable inside an expression via SymPy's subs — and the Args section identifies exactly which three artifacts are involved. This is clearly distinguishable from neighboring expression tools like simplify_expression, expand_expression, or introduce_expression.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The worked example demonstrates the intended call pattern: create variables with intro, build expressions with introduce_expression, then pass the resulting keys into substitute_expression. It conveys the workflow context but never states when not to use it or names an alternative for overlapping tasks.

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.

  1. 39 tool updatesv0.1.0
    • First observedapart_expression
    • First observedcalculate_curl
    • First observedcalculate_divergence
    • First observedcalculate_gradient
    • First observedcalculate_tensor
    • First observedcancel_expression
    • First observedconvert_to_units
    • First observedcreate_coordinate_system
    • First observedcreate_custom_metric
    • First observedcreate_matrix
    • First observedcreate_predefined_metric
    • First observedcreate_vector_field
    • First observeddifferentiate_expression
    • First observeddsolve_ode
    • First observedexpand_expression
    • First observedfactor_expression
    • First observedintegrate_expression
    • First observedintro
    • First observedintro_many
    • First observedintroduce_expression
    • First observedintroduce_function
    • First observedlimit_expression
    • First observedmatrix_determinant
    • First observedmatrix_eigenvalues
    • First observedmatrix_eigenvectors
    • First observedmatrix_inverse
    • First observedpdsolve_pde
    • First observedprint_latex_expression
    • First observedprint_latex_tensor
    • First observedquantity_simplify_units
    • First observedreset_state
    • First observedsearch_predefined_metrics
    • First observedseries_expansion
    • First observedsimplify_expression
    • First observedsolve_algebraically
    • First observedsolve_inequality
    • First observedsolve_linear_system
    • First observedsolve_nonlinear_system
    • First observedsubstitute_expression

TDQS

B3.3/5.0

Scored across 39 tools

Disambiguation4/5

Most tools map to distinct SymPy operations (solve, simplify, factor, integrate, matrix, vector, units), so selection is generally clear. Some overlaps remain: intro vs intro_many, introduce_expression can also create matrices despite create_matrix, and solve_algebraically overlaps conceptually with system solvers, though descriptions mostly clarify.

Naming Consistency4/5

Most names follow readable action-oriented patterns such as solve_*, create_*, calculate_*, and *_expression. Deviations are minor but visible: intro/intro_many, noun-first matrix_* operations, and quantity_simplify_units break the otherwise consistent verb-first convention.

Tool Count2/5

At 39 tools the server is heavily over-scoped relative to a typical MCP tool surface, spanning algebra, calculus, ODE/PDE, matrices, vector calculus, units, and tensors. Even though many tools correspond to real SymPy functions, the count is high enough to burden tool selection and discoverability.

Completeness4/5

The surface covers a broad symbolic algebra lifecycle: variables, expressions, manipulation, solving, calculus, ODE/PDE, matrices, vector calculus, units, and tensors. Minor gaps exist, such as individual listing/deletion of stored objects, numeric evaluation, and fuller matrix arithmetic beyond inverse/determinant/eigen operations.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Related MCP Connectors

Related MCP Servers