"""Dashboard, Chart, Number Card, and Workspace tools.""" import json from mcp.types import Tool from frappe_mcp.client.frappe_api import FrappeClient def tools() -> list[Tool]: return [ Tool( name="frappe_list_dashboards", description="List all Frappe Dashboards.", inputSchema={ "type": "object", "properties": {"limit": {"type": "integer", "default": 20}}, }, ), Tool( name="frappe_get_dashboard", description="Get a Dashboard with all its charts and cards.", inputSchema={ "type": "object", "required": ["name"], "properties": {"name": {"type": "string"}}, }, ), Tool( name="frappe_create_dashboard", description="Create a new Dashboard.", inputSchema={ "type": "object", "required": ["dashboard_name"], "properties": { "dashboard_name": {"type": "string"}, "module": {"type": "string"}, "is_default": {"type": "integer", "default": 0}, "charts": { "type": "array", "items": {"type": "object"}, "description": "List of {chart, width} objects", }, }, }, ), Tool( name="frappe_create_dashboard_chart", description="Create a Dashboard Chart (bar, line, pie, donut, percentage, heatmap).", inputSchema={ "type": "object", "required": ["chart_name", "chart_type", "document_type"], "properties": { "chart_name": {"type": "string"}, "chart_type": { "type": "string", "enum": ["Count", "Sum", "Average", "Min", "Max", "Group By"], }, "document_type": {"type": "string"}, "based_on": {"type": "string", "description": "Date field for time-series grouping"}, "value_based_on": {"type": "string", "description": "Field to aggregate"}, "type": { "type": "string", "enum": ["Bar", "Line", "Percentage", "Pie", "Donut", "Heatmap"], "default": "Bar", }, "timespan": { "type": "string", "enum": ["Last Year", "Last Quarter", "Last Month", "Last Week"], "default": "Last Year", }, "time_interval": { "type": "string", "enum": ["Yearly", "Quarterly", "Monthly", "Weekly", "Daily"], "default": "Monthly", }, "filters_json": {"type": "string", "description": "JSON string of filters"}, "color": {"type": "string"}, }, }, ), Tool( name="frappe_create_number_card", description="Create a Number Card for dashboards showing a single aggregated metric.", inputSchema={ "type": "object", "required": ["name", "document_type", "function"], "properties": { "name": {"type": "string"}, "label": {"type": "string"}, "document_type": {"type": "string"}, "function": { "type": "string", "enum": ["Count", "Sum", "Average", "Min", "Max"], "default": "Count", }, "aggregate_function_based_on": {"type": "string"}, "filters_json": {"type": "string"}, "color": {"type": "string"}, "stats_time_interval": {"type": "string", "enum": ["Daily", "Weekly", "Monthly", "Quarterly", "Yearly"]}, }, }, ), # --- Workspace --- Tool( name="frappe_list_workspaces", description="List all Desk Workspaces.", inputSchema={ "type": "object", "properties": {"limit": {"type": "integer", "default": 30}}, }, ), Tool( name="frappe_get_workspace", description="Get a Workspace with all its shortcuts, links, and charts.", inputSchema={ "type": "object", "required": ["name"], "properties": {"name": {"type": "string"}}, }, ), Tool( name="frappe_create_workspace", description="Create a new Desk Workspace with shortcuts and links.", inputSchema={ "type": "object", "required": ["name"], "properties": { "name": {"type": "string"}, "label": {"type": "string"}, "module": {"type": "string"}, "icon": {"type": "string"}, "is_hidden": {"type": "integer", "default": 0}, "shortcuts": { "type": "array", "items": {"type": "object"}, "description": "List of shortcut objects {label, link_to, type}", }, "links": { "type": "array", "items": {"type": "object"}, "description": "List of link objects for the workspace body", }, }, }, ), Tool( name="frappe_update_workspace", description="Update a Workspace's content, shortcuts, or visibility.", inputSchema={ "type": "object", "required": ["name"], "properties": { "name": {"type": "string"}, "updates": {"type": "object"}, }, }, ), ] def handlers() -> dict: return { "frappe_list_dashboards": _list_dashboards, "frappe_get_dashboard": _get_dashboard, "frappe_create_dashboard": _create_dashboard, "frappe_create_dashboard_chart": _create_dashboard_chart, "frappe_create_number_card": _create_number_card, "frappe_list_workspaces": _list_workspaces, "frappe_get_workspace": _get_workspace, "frappe_create_workspace": _create_workspace, "frappe_update_workspace": _update_workspace, } async def _list_dashboards(args: dict) -> str: client = FrappeClient() result = await client.get_list("Dashboard", fields=["name", "module", "is_default"], limit=args.get("limit", 20)) return json.dumps(result, indent=2) async def _get_dashboard(args: dict) -> str: client = FrappeClient() result = await client.get_doc("Dashboard", args["name"]) return json.dumps(result, indent=2) async def _create_dashboard(args: dict) -> str: client = FrappeClient() result = await client.create_doc("Dashboard", args) return json.dumps(result, indent=2) async def _create_dashboard_chart(args: dict) -> str: client = FrappeClient() result = await client.create_doc("Dashboard Chart", args) return json.dumps(result, indent=2) async def _create_number_card(args: dict) -> str: client = FrappeClient() result = await client.create_doc("Number Card", args) return json.dumps(result, indent=2) async def _list_workspaces(args: dict) -> str: client = FrappeClient() result = await client.get_list("Workspace", fields=["name", "label", "module", "is_hidden"], limit=args.get("limit", 30)) return json.dumps(result, indent=2) async def _get_workspace(args: dict) -> str: client = FrappeClient() result = await client.get_doc("Workspace", args["name"]) return json.dumps(result, indent=2) async def _create_workspace(args: dict) -> str: client = FrappeClient() result = await client.create_doc("Workspace", args) return json.dumps(result, indent=2) async def _update_workspace(args: dict) -> str: client = FrappeClient() result = await client.update_doc("Workspace", args["name"], args.get("updates", {})) return json.dumps(result, indent=2)