Skip to main content
Glama

submit_document

Submit documents in Frappe by changing docstatus from 0 to 1 with validation, error handling, and clear feedback for corrective action.

Instructions

Submit a document in Frappe (change docstatus from 0 to 1). This tool handles document submission using Frappe's submission workflow, including proper validation and error handling to provide clear feedback for corrective action. Args: doctype: DocType name name: Document name (case-sensitive) Returns: Success message if submitted, or detailed error information if submission fails due to validation errors or missing required fields.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
doctypeYes
nameYes

Implementation Reference

  • The core handler function for the 'submit_document' MCP tool. Decorated with @mcp.tool(), it implements the logic to submit a Frappe document by retrieving the document, validating its status, using Frappe's savedocs API with 'Submit' action, and providing detailed error messages for common issues like validation errors, permissions, and missing fields.
    @mcp.tool() async def submit_document( doctype: str, name: str ) -> str: """ Submit a document in Frappe (change docstatus from 0 to 1). This tool handles document submission using Frappe's submission workflow, including proper validation and error handling to provide clear feedback for corrective action. Args: doctype: DocType name name: Document name (case-sensitive) Returns: Success message if submitted, or detailed error information if submission fails due to validation errors or missing required fields. """ try: client = get_client() # First, get the current document to check its status and get full data try: doc_response = await client.get(f"api/resource/{doctype}/{name}") doc_data = doc_response.get("data", {}) current_docstatus = doc_data.get("docstatus", None) if current_docstatus is None: return f"Error: Could not retrieve document {doctype} '{name}'. Document may not exist." if current_docstatus == 1: return f"Document {doctype} '{name}' is already submitted." if current_docstatus == 2: return f"Document {doctype} '{name}' is cancelled and cannot be submitted." if current_docstatus != 0: return f"Document {doctype} '{name}' has unexpected status (docstatus={current_docstatus}). Only draft documents (docstatus=0) can be submitted." except Exception as get_error: return f"Error retrieving document for submission: {get_error}" # Prepare document for submission by setting docstatus to 1 submit_doc = doc_data.copy() submit_doc['docstatus'] = 1 # Use Frappe's savedocs method which handles the submission workflow response = await client.post( "api/method/frappe.desk.form.save.savedocs", json_data={ "doc": json.dumps(submit_doc), "action": "Submit" } ) # Check if submission was successful if "docs" in response: submitted_doc = response["docs"][0] if response["docs"] else {} final_docstatus = submitted_doc.get("docstatus", 0) if final_docstatus == 1: return f"✅ Document {doctype} '{name}' successfully submitted." else: return f"⚠️ Submission completed but document status is {final_docstatus} (expected 1)." # If we get here, check for success without docs if response.get("message") == "ok" or "exc" not in response: return f"✅ Document {doctype} '{name}' successfully submitted." # If no explicit success indicator, assume it worked return f"✅ Document {doctype} '{name}' submission completed." except FrappeApiError as api_error: # Handle specific Frappe API errors with detailed information if api_error.response_data: error_data = api_error.response_data # Check for validation errors in the response if "exception" in error_data: exception_msg = error_data["exception"] # Extract user-friendly error messages if "ValidationError" in str(exception_msg): # Try to extract the specific validation error if "Reference No & Reference Date is required" in str(exception_msg): return ( f"❌ Submission failed: Document {doctype} '{name}' requires 'reference_no' and 'reference_date' fields for Bank Entry vouchers. " f"Please update the document with these required fields before submitting." ) else: # Generic validation error return f"❌ Validation error: {exception_msg}. Please fix the validation issues and try again." elif "PermissionError" in str(exception_msg): return f"❌ Permission denied: You don't have sufficient permissions to submit {doctype} documents." else: # Other exceptions return f"❌ Submission failed: {exception_msg}" # Check for server messages with more details if "_server_messages" in error_data: try: messages = json.loads(error_data["_server_messages"]) if messages: msg_data = json.loads(messages[0]) user_message = msg_data.get("message", "Unknown error") return f"❌ Submission failed: {user_message}" except (json.JSONDecodeError, KeyError, IndexError): pass return f"❌ Submission failed: {api_error}" except Exception as error: return _format_error_response(error, "submit_document")
  • The @mcp.tool() decorator registers the submit_document function as an MCP tool.
    @mcp.tool()
  • Input schema defined by type annotations: doctype (str), name (str), returning str.
    doctype: str, name: str

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/appliedrelevance/frappe-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server