- Implemented server and client script management tools in `frappe_mcp/tools/scripts.py` - Added translation and user permission management tools in `frappe_mcp/tools/translations.py` - Created user and role management tools in `frappe_mcp/tools/users.py` - Developed webhook and API key management tools in `frappe_mcp/tools/webhooks.py` - Introduced workflow management tools in `frappe_mcp/tools/workflow_tools.py` - Added `pyproject.toml` for project metadata and dependencies
218 lines
8.4 KiB
Python
218 lines
8.4 KiB
Python
"""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)
|