"""Print Format tools — create, list, update Frappe Print Formats (Jinja/HTML).""" import json from mcp.types import Tool from frappe_mcp.client.frappe_api import FrappeClient def tools() -> list[Tool]: return [ Tool( name="frappe_list_print_formats", description="List all Print Formats, optionally filtered by DocType.", inputSchema={ "type": "object", "properties": { "doc_type": {"type": "string", "description": "Filter by DocType"}, "limit": {"type": "integer", "default": 30}, }, }, ), Tool( name="frappe_get_print_format", description="Get the full definition of a Print Format including its HTML template.", inputSchema={ "type": "object", "required": ["name"], "properties": { "name": {"type": "string"}, }, }, ), Tool( name="frappe_create_print_format", description=( "Create a new custom Print Format with a Jinja2/HTML template. " "Use {{ doc.field_name }} syntax to access document fields." ), inputSchema={ "type": "object", "required": ["name", "doc_type", "html"], "properties": { "name": {"type": "string"}, "doc_type": {"type": "string", "description": "DocType this format applies to"}, "html": {"type": "string", "description": "Jinja2 HTML template"}, "css": {"type": "string", "description": "Optional custom CSS"}, "standard": {"type": "string", "default": "No", "enum": ["Yes", "No"]}, "disabled": {"type": "integer", "default": 0}, "default_print_language": {"type": "string", "default": "en"}, "print_format_type": { "type": "string", "enum": ["Jinja", "JS"], "default": "Jinja", }, }, }, ), Tool( name="frappe_update_print_format", description="Update an existing Print Format's HTML, CSS, or properties.", inputSchema={ "type": "object", "required": ["name"], "properties": { "name": {"type": "string"}, "html": {"type": "string"}, "css": {"type": "string"}, "disabled": {"type": "integer"}, "updates": {"type": "object", "description": "Any additional fields to update"}, }, }, ), Tool( name="frappe_preview_print_format", description="Get a rendered HTML preview of a Print Format for a specific document.", inputSchema={ "type": "object", "required": ["doctype", "docname", "print_format"], "properties": { "doctype": {"type": "string"}, "docname": {"type": "string"}, "print_format": {"type": "string"}, "letterhead": {"type": "string", "description": "Letterhead name (optional)"}, }, }, ), ] def handlers() -> dict: return { "frappe_list_print_formats": _list_print_formats, "frappe_get_print_format": _get_print_format, "frappe_create_print_format": _create_print_format, "frappe_update_print_format": _update_print_format, "frappe_preview_print_format": _preview_print_format, } async def _list_print_formats(args: dict) -> str: client = FrappeClient() filters = [] if doc_type := args.get("doc_type"): filters.append(["doc_type", "=", doc_type]) result = await client.get_list( "Print Format", fields=["name", "doc_type", "disabled", "standard", "modified"], filters=filters if filters else None, limit=args.get("limit", 30), ) return json.dumps(result, indent=2) async def _get_print_format(args: dict) -> str: client = FrappeClient() result = await client.get_doc("Print Format", args["name"]) return json.dumps(result, indent=2) async def _create_print_format(args: dict) -> str: client = FrappeClient() payload = { "name": args["name"], "doc_type": args["doc_type"], "html": args["html"], "css": args.get("css", ""), "standard": args.get("standard", "No"), "disabled": args.get("disabled", 0), "default_print_language": args.get("default_print_language", "en"), "print_format_type": args.get("print_format_type", "Jinja"), } result = await client.create_doc("Print Format", payload) return json.dumps(result, indent=2) async def _update_print_format(args: dict) -> str: client = FrappeClient() updates = args.get("updates", {}) for field in ("html", "css", "disabled"): if field in args: updates[field] = args[field] result = await client.update_doc("Print Format", args["name"], updates) return json.dumps(result, indent=2) async def _preview_print_format(args: dict) -> str: client = FrappeClient() params = { "doctype": args["doctype"], "name": args["docname"], "print_format": args["print_format"], } if letterhead := args.get("letterhead"): params["letterhead"] = letterhead result = await client.get("/api/method/frappe.www.printview.get_html_and_style", params=params) return json.dumps(result, indent=2)