171 lines
5.8 KiB
Python
171 lines
5.8 KiB
Python
"""Document CRUD tools — create, read, update, delete, list Frappe documents."""
|
|
|
|
import json
|
|
from mcp.types import Tool
|
|
from frappe_mcp.client.frappe_api import FrappeClient
|
|
from frappe_mcp.config import get_settings
|
|
|
|
|
|
def tools() -> list[Tool]:
|
|
return [
|
|
Tool(
|
|
name="frappe_list_documents",
|
|
description="List documents of a given DocType with optional filters.",
|
|
inputSchema={
|
|
"type": "object",
|
|
"required": ["doctype"],
|
|
"properties": {
|
|
"doctype": {"type": "string"},
|
|
"fields": {
|
|
"type": "array",
|
|
"items": {"type": "string"},
|
|
"description": "Fields to return. Defaults to ['name', 'modified'].",
|
|
},
|
|
"filters": {
|
|
"type": "array",
|
|
"items": {},
|
|
"description": "Filter list e.g. [[\"status\", \"=\", \"Open\"]]",
|
|
},
|
|
"limit": {"type": "integer", "default": 20},
|
|
"order_by": {"type": "string", "default": "modified desc"},
|
|
},
|
|
},
|
|
),
|
|
Tool(
|
|
name="frappe_get_document",
|
|
description="Get a single Frappe document by DocType and name.",
|
|
inputSchema={
|
|
"type": "object",
|
|
"required": ["doctype", "name"],
|
|
"properties": {
|
|
"doctype": {"type": "string"},
|
|
"name": {"type": "string"},
|
|
},
|
|
},
|
|
),
|
|
Tool(
|
|
name="frappe_create_document",
|
|
description="Create a new document in any DocType.",
|
|
inputSchema={
|
|
"type": "object",
|
|
"required": ["doctype", "data"],
|
|
"properties": {
|
|
"doctype": {"type": "string"},
|
|
"data": {"type": "object", "description": "Field values for the new document"},
|
|
},
|
|
},
|
|
),
|
|
Tool(
|
|
name="frappe_update_document",
|
|
description="Update fields on an existing document.",
|
|
inputSchema={
|
|
"type": "object",
|
|
"required": ["doctype", "name", "data"],
|
|
"properties": {
|
|
"doctype": {"type": "string"},
|
|
"name": {"type": "string"},
|
|
"data": {"type": "object", "description": "Fields to update"},
|
|
},
|
|
},
|
|
),
|
|
Tool(
|
|
name="frappe_delete_document",
|
|
description="Delete a document. Blocked in read-only mode.",
|
|
inputSchema={
|
|
"type": "object",
|
|
"required": ["doctype", "name"],
|
|
"properties": {
|
|
"doctype": {"type": "string"},
|
|
"name": {"type": "string"},
|
|
},
|
|
},
|
|
),
|
|
Tool(
|
|
name="frappe_submit_document",
|
|
description="Submit a submittable document (changes status to Submitted).",
|
|
inputSchema={
|
|
"type": "object",
|
|
"required": ["doctype", "name"],
|
|
"properties": {
|
|
"doctype": {"type": "string"},
|
|
"name": {"type": "string"},
|
|
},
|
|
},
|
|
),
|
|
Tool(
|
|
name="frappe_cancel_document",
|
|
description="Cancel a submitted document.",
|
|
inputSchema={
|
|
"type": "object",
|
|
"required": ["doctype", "name"],
|
|
"properties": {
|
|
"doctype": {"type": "string"},
|
|
"name": {"type": "string"},
|
|
},
|
|
},
|
|
),
|
|
]
|
|
|
|
|
|
def handlers() -> dict:
|
|
return {
|
|
"frappe_list_documents": _list_documents,
|
|
"frappe_get_document": _get_document,
|
|
"frappe_create_document": _create_document,
|
|
"frappe_update_document": _update_document,
|
|
"frappe_delete_document": _delete_document,
|
|
"frappe_submit_document": _submit_document,
|
|
"frappe_cancel_document": _cancel_document,
|
|
}
|
|
|
|
|
|
async def _list_documents(args: dict) -> str:
|
|
client = FrappeClient()
|
|
result = await client.get_list(
|
|
args["doctype"],
|
|
fields=args.get("fields", ["name", "modified"]),
|
|
filters=args.get("filters"),
|
|
limit=args.get("limit", 20),
|
|
order_by=args.get("order_by", "modified desc"),
|
|
)
|
|
return json.dumps(result, indent=2)
|
|
|
|
|
|
async def _get_document(args: dict) -> str:
|
|
client = FrappeClient()
|
|
result = await client.get_doc(args["doctype"], args["name"])
|
|
return json.dumps(result, indent=2)
|
|
|
|
|
|
async def _create_document(args: dict) -> str:
|
|
client = FrappeClient()
|
|
data = {"doctype": args["doctype"], **args["data"]}
|
|
result = await client.create_doc(args["doctype"], data)
|
|
return json.dumps(result, indent=2)
|
|
|
|
|
|
async def _update_document(args: dict) -> str:
|
|
client = FrappeClient()
|
|
result = await client.update_doc(args["doctype"], args["name"], args["data"])
|
|
return json.dumps(result, indent=2)
|
|
|
|
|
|
async def _delete_document(args: dict) -> str:
|
|
if get_settings().read_only_mode:
|
|
return "Error: read_only_mode is enabled. Deletion blocked."
|
|
client = FrappeClient()
|
|
result = await client.delete_doc(args["doctype"], args["name"])
|
|
return json.dumps(result, indent=2)
|
|
|
|
|
|
async def _submit_document(args: dict) -> str:
|
|
client = FrappeClient()
|
|
result = await client.update_doc(args["doctype"], args["name"], {"docstatus": 1})
|
|
return json.dumps(result, indent=2)
|
|
|
|
|
|
async def _cancel_document(args: dict) -> str:
|
|
client = FrappeClient()
|
|
result = await client.update_doc(args["doctype"], args["name"], {"docstatus": 2})
|
|
return json.dumps(result, indent=2)
|