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

125 lines
4.3 KiB
Python

"""Custom Fields tools — add, modify, remove custom fields on any DocType."""
import json
from mcp.types import Tool
from frappe_mcp.client.frappe_api import FrappeClient
_FIELD_TYPES = [
"Data", "Int", "Float", "Currency", "Percent", "Check",
"Small Text", "Text", "Long Text", "Text Editor", "HTML",
"Date", "Datetime", "Time", "Duration",
"Select", "Link", "Dynamic Link", "Table", "Table MultiSelect",
"Attach", "Attach Image", "Signature", "Color", "Barcode",
"Geolocation", "Rating", "Section Break", "Column Break", "Tab Break",
]
_FIELD_SCHEMA = {
"type": "object",
"required": ["dt", "fieldname", "fieldtype", "label"],
"properties": {
"dt": {"type": "string", "description": "DocType to add the field to"},
"fieldname": {"type": "string"},
"fieldtype": {"type": "string", "enum": _FIELD_TYPES},
"label": {"type": "string"},
"options": {"type": "string", "description": "For Link: target DocType. For Select: newline-separated options."},
"reqd": {"type": "integer", "default": 0},
"in_list_view": {"type": "integer", "default": 0},
"in_standard_filter": {"type": "integer", "default": 0},
"insert_after": {"type": "string", "description": "Fieldname to insert after"},
"default": {"type": "string"},
"description": {"type": "string"},
"hidden": {"type": "integer", "default": 0},
"read_only": {"type": "integer", "default": 0},
"bold": {"type": "integer", "default": 0},
},
}
def tools() -> list[Tool]:
return [
Tool(
name="frappe_add_custom_field",
description="Add a custom field to an existing DocType.",
inputSchema=_FIELD_SCHEMA,
),
Tool(
name="frappe_update_custom_field",
description="Update properties of an existing custom field.",
inputSchema={
"type": "object",
"required": ["dt", "fieldname"],
"properties": {
"dt": {"type": "string"},
"fieldname": {"type": "string"},
"updates": {"type": "object", "description": "Properties to update"},
},
},
),
Tool(
name="frappe_remove_custom_field",
description="Remove a custom field from a DocType.",
inputSchema={
"type": "object",
"required": ["dt", "fieldname"],
"properties": {
"dt": {"type": "string"},
"fieldname": {"type": "string"},
},
},
),
Tool(
name="frappe_list_custom_fields",
description="List all custom fields for a DocType.",
inputSchema={
"type": "object",
"required": ["dt"],
"properties": {
"dt": {"type": "string"},
},
},
),
]
def handlers() -> dict:
return {
"frappe_add_custom_field": _add_custom_field,
"frappe_update_custom_field": _update_custom_field,
"frappe_remove_custom_field": _remove_custom_field,
"frappe_list_custom_fields": _list_custom_fields,
}
async def _add_custom_field(args: dict) -> str:
client = FrappeClient()
payload = {k: v for k, v in args.items()}
result = await client.create_doc("Custom Field", payload)
return json.dumps(result, indent=2)
async def _update_custom_field(args: dict) -> str:
client = FrappeClient()
# Custom Field name is "{DocType}-{fieldname}"
cf_name = f"{args['dt']}-{args['fieldname']}"
result = await client.update_doc("Custom Field", cf_name, args.get("updates", {}))
return json.dumps(result, indent=2)
async def _remove_custom_field(args: dict) -> str:
client = FrappeClient()
cf_name = f"{args['dt']}-{args['fieldname']}"
result = await client.delete_doc("Custom Field", cf_name)
return json.dumps(result, indent=2)
async def _list_custom_fields(args: dict) -> str:
client = FrappeClient()
result = await client.get_list(
"Custom Field",
fields=["name", "fieldname", "fieldtype", "label", "reqd", "hidden"],
filters=[["dt", "=", args["dt"]]],
limit=100,
)
return json.dumps(result, indent=2)