MCP-Frappe/frappe_mcp/tools/email_templates.py
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

221 lines
8.2 KiB
Python

"""Email Template tools — create, list, update Frappe Email Templates and Notifications."""
import json
from mcp.types import Tool
from frappe_mcp.client.frappe_api import FrappeClient
def tools() -> list[Tool]:
return [
Tool(
name="frappe_list_email_templates",
description="List all Email Templates in the system.",
inputSchema={
"type": "object",
"properties": {
"limit": {"type": "integer", "default": 30},
},
},
),
Tool(
name="frappe_get_email_template",
description="Get a specific Email Template including subject and body.",
inputSchema={
"type": "object",
"required": ["name"],
"properties": {
"name": {"type": "string"},
},
},
),
Tool(
name="frappe_create_email_template",
description=(
"Create a new Email Template. Subject and response support Jinja2. "
"Access doc fields with {{ doc.field_name }}."
),
inputSchema={
"type": "object",
"required": ["name", "subject", "response"],
"properties": {
"name": {"type": "string", "description": "Template name/ID"},
"subject": {"type": "string", "description": "Email subject (Jinja2 supported)"},
"response": {"type": "string", "description": "Email body HTML (Jinja2 supported)"},
"use_html": {"type": "integer", "default": 1},
},
},
),
Tool(
name="frappe_update_email_template",
description="Update an Email Template's subject or body.",
inputSchema={
"type": "object",
"required": ["name"],
"properties": {
"name": {"type": "string"},
"subject": {"type": "string"},
"response": {"type": "string"},
"updates": {"type": "object"},
},
},
),
Tool(
name="frappe_list_notifications",
description="List Frappe Notifications (automated email/Slack alerts on DocType events).",
inputSchema={
"type": "object",
"properties": {
"document_type": {"type": "string", "description": "Filter by DocType"},
"enabled": {"type": "integer", "description": "1 = enabled only"},
"limit": {"type": "integer", "default": 30},
},
},
),
Tool(
name="frappe_create_notification",
description=(
"Create a Frappe Notification — triggers an email/Slack/system message "
"on a DocType event or date condition."
),
inputSchema={
"type": "object",
"required": ["name", "document_type", "event", "subject", "message"],
"properties": {
"name": {"type": "string"},
"document_type": {"type": "string"},
"event": {
"type": "string",
"enum": [
"New", "Save", "Submit", "Cancel", "Days Before",
"Days After", "Value Change", "Method", "Custom",
],
},
"subject": {"type": "string", "description": "Email subject (Jinja2)"},
"message": {"type": "string", "description": "Email body (Jinja2 HTML)"},
"send_to_all_assignees": {"type": "integer", "default": 0},
"recipients": {
"type": "array",
"description": "List of recipient rows: [{\"receiver_by_document_field\": \"email\"}]",
"items": {"type": "object"},
},
"condition": {"type": "string", "description": "Python expression e.g. doc.status == 'Open'"},
"channel": {
"type": "string",
"enum": ["Email", "Slack", "System Notification", "SMS"],
"default": "Email",
},
"enabled": {"type": "integer", "default": 1},
},
},
),
Tool(
name="frappe_update_notification",
description="Enable, disable, or update a Notification.",
inputSchema={
"type": "object",
"required": ["name"],
"properties": {
"name": {"type": "string"},
"enabled": {"type": "integer"},
"subject": {"type": "string"},
"message": {"type": "string"},
"updates": {"type": "object"},
},
},
),
]
def handlers() -> dict:
return {
"frappe_list_email_templates": _list_email_templates,
"frappe_get_email_template": _get_email_template,
"frappe_create_email_template": _create_email_template,
"frappe_update_email_template": _update_email_template,
"frappe_list_notifications": _list_notifications,
"frappe_create_notification": _create_notification,
"frappe_update_notification": _update_notification,
}
async def _list_email_templates(args: dict) -> str:
client = FrappeClient()
result = await client.get_list(
"Email Template",
fields=["name", "subject", "modified"],
limit=args.get("limit", 30),
)
return json.dumps(result, indent=2)
async def _get_email_template(args: dict) -> str:
client = FrappeClient()
result = await client.get_doc("Email Template", args["name"])
return json.dumps(result, indent=2)
async def _create_email_template(args: dict) -> str:
client = FrappeClient()
payload = {
"name": args["name"],
"subject": args["subject"],
"response": args["response"],
"use_html": args.get("use_html", 1),
}
result = await client.create_doc("Email Template", payload)
return json.dumps(result, indent=2)
async def _update_email_template(args: dict) -> str:
client = FrappeClient()
updates = args.get("updates", {})
for field in ("subject", "response"):
if field in args:
updates[field] = args[field]
result = await client.update_doc("Email Template", args["name"], updates)
return json.dumps(result, indent=2)
async def _list_notifications(args: dict) -> str:
client = FrappeClient()
filters = []
if dt := args.get("document_type"):
filters.append(["document_type", "=", dt])
if "enabled" in args:
filters.append(["enabled", "=", args["enabled"]])
result = await client.get_list(
"Notification",
fields=["name", "document_type", "event", "channel", "enabled"],
filters=filters if filters else None,
limit=args.get("limit", 30),
)
return json.dumps(result, indent=2)
async def _create_notification(args: dict) -> str:
client = FrappeClient()
payload = {
"name": args["name"],
"document_type": args["document_type"],
"event": args["event"],
"subject": args["subject"],
"message": args["message"],
"channel": args.get("channel", "Email"),
"enabled": args.get("enabled", 1),
"send_to_all_assignees": args.get("send_to_all_assignees", 0),
"recipients": args.get("recipients", []),
"condition": args.get("condition", ""),
}
result = await client.create_doc("Notification", payload)
return json.dumps(result, indent=2)
async def _update_notification(args: dict) -> str:
client = FrappeClient()
updates = args.get("updates", {})
for field in ("enabled", "subject", "message"):
if field in args:
updates[field] = args[field]
result = await client.update_doc("Notification", args["name"], updates)
return json.dumps(result, indent=2)