MOHAN 2ee93048e1 feat: Add tools for managing server scripts, client scripts, translations, assignment rules, user permissions, webhooks, API keys, and workflows
- 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
2026-04-21 20:26:45 +05:30

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)