plot_line_chart
Generate line charts from Teradata data to visualize trends and relationships between specified columns and labels for analysis.
Instructions
Function to generate a line plot for labels and columns. Columns mentioned in labels are used for x-axis and columns are used for y-axis.
PARAMETERS: table_name: Required Argument. Specifies the name of the table to generate the donut plot. Types: str
labels:
Required Argument.
Specifies the labels to be used for the line plot.
Types: str
columns:
Required Argument.
Specifies the column to be used for generating the line plot.
Types: List[str]
RETURNS: dict
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| table_name | Yes | ||
| labels | Yes | ||
| columns | Yes |
Implementation Reference
- The main handler function for the 'plot_line_chart' MCP tool. It validates inputs, ensures labels is a string column name, and delegates to the get_plot_json_data helper to query the Teradata table and format Chart.js line chart data.def handle_plot_line_chart(conn: TeradataConnection, table_name: str, labels: str, columns: str|List[str]): """ Function to generate a line plot for labels and columns. Columns mentioned in labels are used for x-axis and columns are used for y-axis. PARAMETERS: table_name: Required Argument. Specifies the name of the table to generate the donut plot. Types: str labels: Required Argument. Specifies the labels to be used for the line plot. Types: str columns: Required Argument. Specifies the column to be used for generating the line plot. Types: List[str] RETURNS: dict """ # Labels must be always a string which represents a column. if not isinstance(labels, str): raise ValueError("labels must be a string representing the column name for x-axis.") return get_plot_json_data(conn, table_name, labels, columns)
- Supporting utility that constructs SQL query, executes it on the connection, processes results into Chart.js-compatible JSON structure with labels and datasets, handles colors, and wraps in a standardized response format.def get_plot_json_data(conn, table_name, labels, columns, chart_type='line'): """ Helper function to fetch data from a Teradata table and formats it for plotting. Right now, designed only to support line plots from chart.js . """ # Define the colors first. colors = ['rgb(75, 192, 192)', '#99cbba', '#d7d0c4', '#fac778', '#e46c59', '#F9CB99', '#280A3E', '#F2EDD1', '#689B8A'] # Chart properties. Every chart needs different property for colors. chart_properties = {'line': 'borderColor', 'polar': 'backgroundColor', 'pie': 'backgroundColor'} columns = [columns] if isinstance(columns, str) else columns sql = "select {labels}, {columns} from {table_name} order by {labels}".format( labels=labels, columns=','.join(columns), table_name=table_name) # Prepare the statement. with conn.cursor() as cur: recs = cur.execute(sql).fetchall() # Define the structure of the chart data. Below is the structure expected by chart.js # { # labels: labels, # datasets: [{ # label: 'My First Dataset', # data: [65, 59, 80, 81, 56, 55, 40], # fill: false, # borderColor: 'rgb(75, 192, 192)', # tension: 0.1 # }] # } labels = [] datasets = [[] for _ in range(len(columns))] for rec in recs: labels.append(rec[0]) for i_, val in enumerate(rec[1:]): datasets[i_].append(val) # Prepare the datasets for chart.js datasets_ = [] for i, dataset in enumerate(datasets): datasets_.append({ 'label': columns[i], 'data': dataset, 'borderColor': colors[i], 'fill': False }) # For polar plot, every dataset needs different colors. if chart_type in ('polar', 'pie'): for i, dataset in enumerate(datasets_): # Remove borderColor and add backgroundColor dataset.pop('borderColor', None) dataset['backgroundColor'] = colors chart_data = {"labels": [str(l) for l in labels], "datasets": datasets_} logger.debug("Chart data: %s", json.dumps(chart_data, indent=2)) return create_response(data=chart_data, metadata={ "tool_description": "chart js {} plot data".format(chart_type), "table_name": table_name, "labels": labels, "columns": columns })
- src/teradata_mcp_server/app.py:461-487 (registration)Dynamic registration code that loads modules via ModuleLoader, discovers functions starting with 'handle_', derives tool name by removing 'handle_' prefix (e.g., handle_plot_line_chart -> plot_line_chart), wraps the handler with MCP adapter (injects DB connection, QueryBand, etc.), and registers it as an MCP tool using mcp.tool.# Register code tools via module loader module_loader = td.initialize_module_loader(config) if module_loader: all_functions = module_loader.get_all_functions() for name, func in all_functions.items(): if not (inspect.isfunction(func) and name.startswith("handle_")): continue tool_name = name[len("handle_"):] if not any(re.match(p, tool_name) for p in config.get('tool', [])): continue # Skip template tools (used for developer reference only) if tool_name.startswith("tmpl_"): logger.debug(f"Skipping template tool: {tool_name}") continue # Skip BAR tools if BAR functionality is disabled if tool_name.startswith("bar_") and not enableBAR: logger.info(f"Skipping BAR tool: {tool_name} (BAR functionality disabled)") continue # Skip chat completion tools if chat completion functionality is disabled if tool_name.startswith("chat_") and not enableChat: logger.info(f"Skipping chat completion tool: {tool_name} (chat completion functionality disabled)") continue wrapped = make_tool_wrapper(func) mcp.tool(name=tool_name, description=wrapped.__doc__)(wrapped) logger.info(f"Created tool: {tool_name}") logger.debug(f"Tool Docstring: {wrapped.__doc__}") else:
- Package init file that imports plot_tools and plot_utils, making the handle_plot_line_chart handler and helpers available for discovery by the module loader.from .plot_resources import * from .plot_tools import * from .plot_utils import *