Skip to main content
Glama
phuihock

TA-Lib MCP Server

by phuihock

calculate_rsi

Calculate the Relative Strength Index (RSI) to identify overbought or oversold conditions in financial markets using price data.

Instructions

Calculate Relative Strength Index (RSI).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
kwargsYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The MCP tool handler function for 'calculate_rsi'. It retrieves the RSI indicator from the registry, creates MarketData from input close prices, calls the indicator's calculate method, and returns the result or error.
    @mcp.tool()
    async def calculate_rsi(
        close: List[float],
        timeperiod: int = 14
    ) -> Dict[str, Any]:
        """Calculate Relative Strength Index (RSI).
        
        Args:
            close: List of closing prices
            timeperiod: Number of periods for RSI (default: 14)
            
        Returns:
            Dictionary with RSI values and metadata
        """
        try:
            # Get indicator from registry
            indicator = registry.get_indicator("rsi")
            if not indicator:
                raise ValueError("RSI indicator not found")
            
            # Create market data
            market_data = MarketData(close=close)
            
            # Calculate indicator
            result = await indicator.calculate(market_data, {"timeperiod": timeperiod})
            
            if result.success:
                return {
                    "success": True,
                    "values": result.values,
                    "metadata": result.metadata,
                }
            else:
                return {
                    "success": False,
                    "error": result.error_message,
                }
                
        except Exception as e:
            return {
                "success": False,
                "error": str(e),
            }
  • Core implementation of RSI calculation in RSIIndicator.calculate(). Computes price deltas, separates gains/losses, applies exponential moving average smoothing for avg gain/loss, computes RS and RSI values.
    async def calculate(
        self, 
        market_data: MarketData, 
        options: Dict[str, Any] = None
    ) -> IndicatorResult:
        """Calculate RSI indicator."""
        if options is None:
            options = {}
        
        timeperiod = options.get("timeperiod", 14)
        close_prices = market_data.close
        
        if len(close_prices) < timeperiod + 1:
            return IndicatorResult(
                indicator_name=self.name,
                success=False,
                values={},
                error_message=f"Not enough data points. Need at least {timeperiod + 1}, got {len(close_prices)}"
            )
        
        # Calculate price changes
        deltas = [close_prices[i] - close_prices[i-1] for i in range(1, len(close_prices))]
        
        # Separate gains and losses
        gains = [d if d > 0 else 0 for d in deltas]
        losses = [-d if d < 0 else 0 for d in deltas]
        
        # Calculate initial average gain and loss
        avg_gain = sum(gains[:timeperiod]) / timeperiod
        avg_loss = sum(losses[:timeperiod]) / timeperiod
        
        rsi_values = []
        
        # Calculate subsequent values using exponential smoothing
        for i in range(timeperiod, len(gains)):
            avg_gain = (avg_gain * (timeperiod - 1) + gains[i]) / timeperiod
            avg_loss = (avg_loss * (timeperiod - 1) + losses[i]) / timeperiod
            
            # Calculate RS (Relative Strength)
            if avg_loss == 0:
                rs = float('inf')
            else:
                rs = avg_gain / avg_loss
            
            # Calculate RSI: 100 - (100 / (1 + RS))
            rsi = 100 - (100 / (1 + rs))
            rsi_values.append(min(max(rsi, 0), 100))  # Clamp between 0 and 100
        
        return IndicatorResult(
            indicator_name=self.name,
            success=True,
            values={"rsi": rsi_values},
            metadata={
                "timeperiod": timeperiod,
                "input_points": len(close_prices),
                "output_points": len(rsi_values)
            }
        )
  • Registration of the RSIIndicator class in the global indicator registry.
    registry.register("rsi", RSIIndicator)
  • Input schema definition for the RSI indicator, defining expected parameters and types.
    def input_schema(self) -> Dict[str, Any]:
        return {
            "type": "object",
            "properties": {
                "close_prices": {
                    "type": "array",
                    "items": {"type": "number"},
                    "description": "List of closing prices"
                },
                "timeperiod": {
                    "type": "integer",
                    "default": 14,
                    "description": "Number of periods for RSI calculation"
                }
            },
            "required": ["close_prices"]
        }
Behavior1/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. The description only states what the tool does without any information about how it behaves—such as input format requirements, computational characteristics, error handling, or output structure. This leaves critical behavioral traits undocumented.

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 extremely concise with a single sentence that directly states the tool's function. There is no wasted language or unnecessary elaboration, making it front-loaded and efficient. However, this conciseness comes at the cost of completeness.

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?

Given the complexity of financial calculations, one parameter with 0% schema coverage, no annotations, and the presence of an output schema, the description is incomplete. It does not explain what data the tool expects, how to format inputs, or what the output represents. The output schema existence reduces the need to describe return values, but other critical context is missing.

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

Parameters1/5

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

The input schema has 0% description coverage with one required parameter 'kwargs' of type string. The description provides no information about what 'kwargs' should contain (e.g., price data, period length), its format, or examples. With low schema coverage, the description fails to compensate, leaving parameters completely unexplained.

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 states the tool calculates the Relative Strength Index (RSI), which is a specific financial technical indicator. However, it does not distinguish this tool from its many siblings (e.g., calculate_ema, calculate_sma) beyond naming the specific indicator. The purpose is clear but lacks differentiation from similar tools.

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 description provides no guidance on when to use this tool versus alternatives. With 17 sibling tools for various technical calculations, there is no indication of when RSI is appropriate compared to other indicators like Bollinger Bands (calculate_bbands) or moving averages. No prerequisites or exclusions are mentioned.

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/phuihock/mcp-talib'

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