Skip to main content
Glama
IBM

Physics MCP Server

by IBM

calculate_beam_reactions

Calculate reaction forces at supports of a simply supported beam under point loads. Solves moment equilibrium to output left and right reactions, total load, and balance check.

Instructions

Calculate reaction forces for a simply supported beam.

Uses moment equilibrium about supports to find reaction forces.

Args:
    beam_length: Beam length in meters
    loads: Point loads in Newtons (downward positive) (or JSON string)
    load_positions: Positions of loads from left end in meters (or JSON string)

Returns:
    Dict containing:
        - reaction_left: Reaction force at left support in Newtons
        - reaction_right: Reaction force at right support in Newtons
        - total_load: Total downward load in Newtons
        - is_balanced: Whether reactions balance loads

Example - Beam with two loads:
    result = await calculate_beam_reactions(
        beam_length=10.0,
        loads=[1000, 500],
        load_positions=[3.0, 7.0]
    )

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
beam_lengthYes
loadsYes
load_positionsYes

Implementation Reference

  • MCP tool handler for calculate_beam_reactions - async function decorated with @tool. Parses JSON string inputs, creates a BeamReactionRequest, calls the core calculation function, and returns the response dict.
    @tool  # type: ignore[arg-type]
    async def calculate_beam_reactions(
        beam_length: float,
        loads: list[float] | str,
        load_positions: list[float] | str,
    ) -> dict:
        """Calculate reaction forces for a simply supported beam.
    
        Uses moment equilibrium about supports to find reaction forces.
    
        Args:
            beam_length: Beam length in meters
            loads: Point loads in Newtons (downward positive) (or JSON string)
            load_positions: Positions of loads from left end in meters (or JSON string)
    
        Returns:
            Dict containing:
                - reaction_left: Reaction force at left support in Newtons
                - reaction_right: Reaction force at right support in Newtons
                - total_load: Total downward load in Newtons
                - is_balanced: Whether reactions balance loads
    
        Example - Beam with two loads:
            result = await calculate_beam_reactions(
                beam_length=10.0,
                loads=[1000, 500],
                load_positions=[3.0, 7.0]
            )
        """
        from ..statics import BeamReactionRequest
        from ..statics import calculate_beam_reactions as calc_beam
    
        if isinstance(loads, str):
            loads = json.loads(loads)
        if isinstance(load_positions, str):
            load_positions = json.loads(load_positions)
    
        request = BeamReactionRequest(
            beam_length=beam_length,
            loads=loads,
            load_positions=load_positions,
        )
        response = calc_beam(request)
        return response.model_dump()
  • Core calculation function for beam reactions - uses moment equilibrium about left support (ΣM_left=0) to find reaction_right, then force equilibrium (ΣF_y=0) to find reaction_left. Validates load positions are within beam length.
    def calculate_beam_reactions(request: BeamReactionRequest) -> BeamReactionResponse:
        """Calculate reaction forces for a simply supported beam with point loads.
    
        Uses moment equilibrium about left support:
        Σ M_left = 0: R_right × L - Σ(P_i × x_i) = 0
    
        Then force equilibrium:
        Σ F_y = 0: R_left + R_right - Σ P_i = 0
    
        Args:
            request: Beam reaction request
    
        Returns:
            Reaction forces at supports
        """
        if len(request.loads) != len(request.load_positions):
            raise ValueError("Number of loads must equal number of positions")
    
        # Check that all positions are within beam length
        for pos in request.load_positions:
            if pos < 0 or pos > request.beam_length:
                raise ValueError(f"Load position {pos}m is outside beam length {request.beam_length}m")
    
        total_load = sum(request.loads)
    
        # Moment about left support
        moment_about_left = sum(load * pos for load, pos in zip(request.loads, request.load_positions))
    
        # R_right from moment equilibrium
        reaction_right = moment_about_left / request.beam_length
    
        # R_left from force equilibrium
        reaction_left = total_load - reaction_right
    
        # Check if balanced
        is_balanced = abs((reaction_left + reaction_right) - total_load) < 0.01
    
        return BeamReactionResponse(
            reaction_left=reaction_left,
            reaction_right=reaction_right,
            total_load=total_load,
            is_balanced=is_balanced,
        )
  • BeamReactionRequest Pydantic model - input schema with beam_length (float, >0), loads (list of floats), and load_positions (list of floats).
    class BeamReactionRequest(BaseModel):
        """Request for beam reaction force calculation (simple supported beam)."""
    
        beam_length: float = Field(..., description="Beam length in meters", gt=0.0)
        loads: list[float] = Field(..., description="Point loads in Newtons (downward positive)")
        load_positions: list[float] = Field(
            ..., description="Positions of loads from left end in meters"
        )
  • BeamReactionResponse Pydantic model - output schema with reaction_left, reaction_right, total_load (floats), and is_balanced (bool).
    class BeamReactionResponse(BaseModel):
        """Response for beam reaction forces."""
    
        reaction_left: float = Field(..., description="Reaction force at left support in Newtons")
        reaction_right: float = Field(..., description="Reaction force at right support in Newtons")
        total_load: float = Field(..., description="Total downward load in Newtons")
        is_balanced: bool = Field(..., description="Whether reactions balance loads")
  • Registration via import of the tools.statics module in server.py - imports the module which triggers @tool decorator registration of all statics tools including calculate_beam_reactions.
    # Import all tools modules to register their @tool decorated functions
    from .tools import (
        basic,
        rotational,
        oscillations,
        circular_motion,
        collisions,
        conservation,
        fluid as fluid_tools,
        kinematics_tools,
        statics,
        convert_units as unit_conversion_tools,
    )
    
    # Silence unused import warnings - these imports register @tool decorated functions
    _ = (
        basic,
        unit_conversion_tools,
        rotational,
        oscillations,
        circular_motion,
        collisions,
        conservation,
        fluid_tools,
        kinematics_tools,
        statics,
    )
Behavior3/5

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

Without annotations, description carries full burden. It mentions downward positive loads and returns a dict, but lacks edge case handling (e.g., invalid inputs, distributed loads). Partially transparent.

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?

Structured with Args, Returns, and Example. Informative but slightly verbose; could be trimmed without losing clarity.

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?

No output schema, so description includes return dict. Covers basic beam reaction calculation. Missing error handling and units consistency, but sufficient for simple use.

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?

Adds meaning beyond schema: loads and load_positions are described as point loads in Newtons and positions in meters, with 'or JSON string'. beam_length only gets 'in meters'. Schema coverage 0% makes this valuable.

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?

Description clearly states 'Calculate reaction forces for a simply supported beam', which is a specific verb+resource. It distinguishes from sibling tools like calculate_force or calculate_torque.

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 an example and explains the method (moment equilibrium). Does not explicitly state when not to use or alternatives, but the tool is unique among siblings.

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

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/IBM/chuk-mcp-physics'

If you have feedback or need assistance with the MCP directory API, please join our Discord server