- 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
125 lines
4.3 KiB
Python
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)
|