82 lines
4.2 KiB
Python
82 lines
4.2 KiB
Python
"""RollCalc's minimal stdio MCP server."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from rollcalc_mcp_tools import (
|
|
analyze_transport_capacity_result,
|
|
calculate_roll_diameter_result,
|
|
get_article_result,
|
|
)
|
|
from transport_calculation import TransportPresetKey
|
|
|
|
|
|
def create_server() -> Any:
|
|
"""Create the stdio-only MCP server after the SDK is installed."""
|
|
from mcp.server.fastmcp import FastMCP
|
|
|
|
server = FastMCP("RollCalc")
|
|
|
|
@server.tool()
|
|
def get_article(
|
|
article_number: str | None = None,
|
|
article_name_hint: str | None = None,
|
|
) -> dict[str, Any]:
|
|
"""Resolve RollCalc article master data. article_number is text (including leading zeroes); optional article_name_hint preserves existing conflict and ambiguity checks."""
|
|
return get_article_result(article_number, article_name_hint)
|
|
|
|
@server.tool()
|
|
def calculate_roll_diameter(
|
|
roll_length_m: float | None = None,
|
|
core_diameter_mm: float | None = None,
|
|
thickness_mm: float | None = None,
|
|
thickness_stddev_mm: float | None = None,
|
|
article_number: str | None = None,
|
|
article_name_hint: str | None = None,
|
|
core_type: str | None = None,
|
|
width_m: float | None = None,
|
|
area_weight_g_m2: float | None = None,
|
|
category: str | None = None,
|
|
production_site: str | None = None,
|
|
) -> dict[str, Any]:
|
|
"""Calculate roll diameter and weight for one roll. roll_length_m is the material length on one roll in m; core_diameter_mm, thickness_mm, and thickness_stddev_mm are mm; width_m is m; and area_weight_g_m2 is g/m². Resolve an article or provide applicable manual material inputs. This MCP tool always returns roll_weight_kg when the required width_m and area_weight_g_m2 inputs are available. On success, transport_roll_inputs contains the browser-equivalent transport values; pass that bundle's fields unchanged to analyze_transport_capacity."""
|
|
return calculate_roll_diameter_result(
|
|
article_number=article_number,
|
|
article_name_hint=article_name_hint,
|
|
roll_length_m=roll_length_m,
|
|
width_m=width_m,
|
|
thickness_mm=thickness_mm,
|
|
thickness_stddev_mm=thickness_stddev_mm,
|
|
area_weight_g_m2=area_weight_g_m2,
|
|
core_diameter_mm=core_diameter_mm,
|
|
core_type=core_type,
|
|
category=category,
|
|
production_site=production_site,
|
|
)
|
|
|
|
@server.tool()
|
|
def analyze_transport_capacity(
|
|
transport_preset: TransportPresetKey,
|
|
roll_diameter_mm: float,
|
|
core_diameter_mm: float,
|
|
roll_width_m: float,
|
|
roll_weight_kg: float,
|
|
product_length_m: float,
|
|
) -> dict[str, Any]:
|
|
"""Use this tool when the user asks how many rolls fit on a known RollCalc transport type. A named transport type is already fully defined by its RollCalc preset: do not ask the user for vehicle dimensions or payload, and do not estimate or invent vehicle data. Use these canonical mappings: LKW-Sattelzug -> lkw_sattelzug; LKW-Tandem -> lkw_tandem; 20ft Container -> container_20ft; 40ft Container -> container_40ft; 40ft High Cube -> container_40ft_hc. If the user asks how many rolls fit on an LKW-Sattelzug, call this tool with transport_preset=\"lkw_sattelzug\". For a chained request, first call get_article and calculate_roll_diameter, then pass every field from its transport_roll_inputs bundle unchanged: roll_diameter_mm, core_diameter_mm, roll_width_m, roll_weight_kg, and product_length_m. Do not choose among minimum, average, or maximum diameter; the bundle contains the browser-equivalent nominal transport diameter. product_length_m is used for reported m², not placement geometry. This stateless tool does not recalculate a roll; roll_weight_kg is consumed exactly as supplied."""
|
|
return analyze_transport_capacity_result(
|
|
transport_preset=transport_preset,
|
|
roll_diameter_mm=roll_diameter_mm,
|
|
core_diameter_mm=core_diameter_mm,
|
|
roll_width_m=roll_width_m,
|
|
roll_weight_kg=roll_weight_kg,
|
|
product_length_m=product_length_m,
|
|
)
|
|
|
|
return server
|
|
|
|
|
|
if __name__ == "__main__":
|
|
create_server().run(transport="stdio")
|