Skip to main content
Glama
Frappe MCP Server

Frappe MCP Server

Call a whitelisted server method

frappe_run_method
Destructive

Execute a whitelisted server-side Python method on a Frappe site for tasks beyond CRUD, such as submitting documents, running reports, or calling custom app APIs.

Instructions

Call a whitelisted server-side Python method on the Frappe site. Use as the escape hatch for anything the CRUD tools cannot express — submitting or cancelling documents, running reports, computing stock balances, or invoking a custom app's API. Use frappe_get_doc, frappe_search_docs, frappe_create_doc or frappe_update_doc for ordinary record work: they validate their arguments and describe their effects, whereas this tool cannot. Behavior: the effect is determined entirely by the method named and may read, write, delete or enqueue background jobs, so treat every call as potentially destructive and non-idempotent unless the method is known to be safe. The target must be decorated with @frappe.whitelist(); anything else raises a permission error, as does a method whose own permission checks reject the API user. Calls run synchronously and are subject to the server's request timeout (FRAPPE_TIMEOUT, 30s by default). Parameters: method is the full dotted import path — module path plus function name — not a DocType method name or a REST path. kwargs maps onto that method's named arguments exactly; names come from its signature, and an unexpected or missing key raises a Frappe error rather than being ignored. Values must be JSON-serialisable, with dates passed as 'YYYY-MM-DD' strings. Omitting kwargs calls the method with no arguments. Returns: {"message": ...} — the method's return value, whose type depends entirely on the method called.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "method": "<method>"
    },
    "name": "frappe_run_method"
  }
}

Input Schema

NameRequiredDescriptionDefault
kwargsNoOptional keyword arguments passed to the remote method. Keys must match that method's parameter names exactly — they depend entirely on the method being called, and an unknown key raises an error rather than being ignored. Values must be JSON-serialisable; pass dates as 'YYYY-MM-DD' strings. Example for stock balance: {'item_code': 'ITEM-001', 'warehouse': 'Stores - W'}. Defaults to no arguments when omitted.
methodYesFull dotted Python path to the whitelisted method — module path plus function name. Examples: 'frappe.auth.get_logged_user', 'frappe.client.submit', 'erpnext.stock.utils.get_stock_balance', or any custom whitelisted method from an installed Frappe app. Not a REST path and not a DocType method name.

Output Schema

NameRequiredDescriptionDefault
messageNoThe value returned by the whitelisted method. The type is whatever that method returns — object, array, string, number, boolean or null. Absent when the method returns nothing.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed6 schema fields changedv1.2.0
    • addedInput schema / additionalProperties
      Added value: +false
    • changedInput schema / properties / kwargs / description
      Previous value: -"Optional dictionary of keyword arguments to pass to the remote method. The keys and expected values depend entirely on the specific method being called. Example for stock balance: {'item_code': 'ITEM-001', 'warehouse': 'Stores - W'}. Defaults to an empty dict when omitted."New value: +"Optional keyword arguments passed to the remote method. Keys must match that method's parameter names exactly — they depend entirely on the method being called, and an unknown key raises an error rather than being ignored. Values must be JSON-serialisable; pass dates as 'YYYY-MM-DD' strings. Example for stock balance: {'item_code': 'ITEM-001', 'warehouse': 'Stores - W'}. Defaults to no arguments when omitted."
    • changedInput schema / properties / method / description
      Previous value: -"Dotted Python path to the whitelisted method to call. Examples: 'frappe.auth.get_logged_user', 'frappe.utils.get_stock_balance', 'erpnext.stock.utils.get_stock_balance', or any custom whitelisted method from your Frappe app."New value: +"Full dotted Python path to the whitelisted method — module path plus function name. Examples: 'frappe.auth.get_logged_user', 'frappe.client.submit', 'erpnext.stock.utils.get_stock_balance', or any custom whitelisted method from an installed Frappe app. Not a REST path and not a DocType method name."
    • changedInput schema / properties / method / examples
      Previous value: -[
      -  "frappe.auth.get_logged_user",
      -  "frappe.utils.get_stock_balance",
      -  "erpnext.stock.utils.get_stock_balance"
      -]New value: +[
      +  "frappe.auth.get_logged_user",
      +  "frappe.client.submit",
      +  "erpnext.stock.utils.get_stock_balance"
      +]
    • addedInput schema / properties / method / minLength
      Added value: +1
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "additionalProperties": true,
      +  "properties": {
      +    "message": {
      +      "description": "The value returned by the whitelisted method. The type is whatever that method returns — object, array, string, number, boolean or null. Absent when the method returns nothing."
      +    }
      +  },
      +  "type": "object"
      +}
  2. Changed4 schema fields changedv1.1.0
    • changedInput schema / properties / kwargs / description
      Previous value: -"Keyword arguments to pass to the method."New value: +"Optional dictionary of keyword arguments to pass to the remote method. The keys and expected values depend entirely on the specific method being called. Example for stock balance: {'item_code': 'ITEM-001', 'warehouse': 'Stores - W'}. Defaults to an empty dict when omitted."
    • addedInput schema / properties / kwargs / examples
      Added value: +[
      +  {
      +    "item_code": "ITEM-001",
      +    "warehouse": "Stores - W"
      +  },
      +  {
      +    "from_date": "2025-01-01",
      +    "to_date": "2025-12-31"
      +  }
      +]
    • changedInput schema / properties / method / description
      Previous value: -"Dotted path to the method (e.g. 'frappe.auth.get_logged_user' or 'erpnext.stock.utils.get_stock_balance')."New value: +"Dotted Python path to the whitelisted method to call. Examples: 'frappe.auth.get_logged_user', 'frappe.utils.get_stock_balance', 'erpnext.stock.utils.get_stock_balance', or any custom whitelisted method from your Frappe app."
    • addedInput schema / properties / method / examples
      Added value: +[
      +  "frappe.auth.get_logged_user",
      +  "frappe.utils.get_stock_balance",
      +  "erpnext.stock.utils.get_stock_balance"
      +]
  3. First observedv1.0.0

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructiveHint=true, openWorldHint=true and idempotentHint=false, and the description reinforces rather than merely repeats this: the effect is determined entirely by the named method, it may read/write/delete/enqueue, and calls should be treated as potentially destructive and non-idempotent unless known safe. It adds auth requirements (@frappe.whitelist() decorator, method-level permission checks) and the synchronous 30s FRAPPE_TIMEOUT constraint — exactly the context annotations cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well front-loaded and clearly segmented with 'Behavior:', 'Parameters:', 'Returns:' labels, so an agent can scan for the needed section. The Parameters section largely duplicates the schema text, which is the one place sentences do not fully earn their place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a high-variance, open-world mutation tool this covers what an agent needs: generic dispatch semantics, permission preconditions, timeout behavior, argument-mapping failure modes, and the envelope shape. An output schema exists, yet the one-line 'Returns: {"message": ...}' is a useful, non-wasteful addition.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and both parameter descriptions already state the dotted-path requirement, the exact-signature match for kwargs keys, the error on unknown keys, and the YYYY-MM-DD date convention. The description's 'Parameters:' paragraph restates nearly all of this, only adding the sharper negative framing 'not a DocType method name or a REST path'. Baseline 3 applies when the schema carries the load and the description adds little.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Call a whitelisted server-side Python method on the Frappe site') and immediately positions itself relative to the CRUD siblings, naming all four by name. An agent can tell from the first two sentences exactly what this tool does and when it is the only option.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly defines the tool as the 'escape hatch' and gives concrete use cases (submit/cancel documents, run reports, compute stock balances, custom app APIs). It also names the alternatives and the condition selecting them: 'Use frappe_get_doc, frappe_search_docs, frappe_create_doc or frappe_update_doc for ordinary record work' because they validate arguments and describe effects.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.