Working with Forms

Forms are the primary way to read and write data in Priority ERP. The MCP server provides four tools for working with forms: form_columns, form_tree, form_fetch, and form_update.

Note: Actions (Direct Activations) are not currently supported through the MCP server. Workflows that depend on form-level Actions must be performed through the Priority UI.

Overview

A typical workflow for working with forms:

  1. Discover – Use entity_search to find the form name, then form_columns and form_tree to understand its structure
  2. Read – Use form_fetch to retrieve records with filters
  3. Write – Use form_update to create or modify records

Discovering Form Structure

Before fetching or updating data, understand the form’s columns and hierarchy.

Get columns for a form:

Call form_columns with the form name to see all available fields, their types, which are keys, which are mandatory, and which link to other forms.

Example: to explore the ORDERS form structure, call form_columns with root_form_name: "ORDERS".

Get the subform tree:

Call form_tree to see parent-child relationships. For example, ORDERS has subforms like ORDERITEMS (order lines), ORDERSTEXT (order text), and others.

To get columns of a subform, pass both root_form_name (the root) and form_name (the subform).

Fetching Records

Use form_fetch to retrieve records. The simplest query specifies just a form name:

{
  "company_name": "mycompany",
  "form_tree": {
    "form_name": "CUSTOMERS",
    "top": 10
  }
}

This returns the first 10 customer records.

Default limit: When top is omitted, results are capped at 100 records with no truncation indicator in the response. Always specify top explicitly to control how many records you receive, and use skip to paginate through larger result sets.

Filtering and Sorting

Add filters to narrow results and sort to control ordering:

{
  "company_name": "mycompany",
  "form_tree": {
    "form_name": "ORDERS",
    "filters": [
      {
        "column_name": "CURDATE",
        "operator": "ge",
        "values": ["01/01/26"]
      },
      {
        "column_name": "ORDSTATUSDES",
        "operator": "ne",
        "values": ["Closed"]
      }
    ],
    "sort": [
      { "column_name": "CURDATE", "descending": true }
    ],
    "top": 20
  }
}

Available operators: eq, ne, gt, lt, ge, le, like, in

Pattern matching with like:

  • * matches any sequence of characters (e.g., "ABC*" matches ABC123, ABCDEF)
  • % matches any single character (e.g., "A%C" matches ABC, ADC)

Nested Subforms

Fetch parent and child records in a single call using the subforms array:

{
  "company_name": "mycompany",
  "form_tree": {
    "form_name": "ORDERS",
    "filters": [
      { "column_name": "ORDNAME", "operator": "eq", "values": ["SO24001234"] }
    ],
    "subforms": [
      {
        "form_name": "ORDERITEMS",
        "sort": [{ "column_name": "KLINE" }]
      }
    ]
  }
}

This returns the order and its line items in one response. Subforms can be nested further for deeper hierarchies.

Creating Records

To create a new record, call form_update with an empty record_keys array and provide only the fields you want to set:

{
  "company_name": "mycompany",
  "root_form": {
    "form_name": "ORDERS",
    "record_keys": [],
    "field_updates": [
      { "name": "CUSTNAME", "value": "1291005" }
    ]
  },
  "subforms": [
    {
      "form_name": "ORDERITEMS",
      "records": [
        {
          "record_keys": [],
          "field_updates": [
            { "name": "PARTNAME", "value": "PRT001" },
            { "name": "DUEDATE", "value": "01/09/26" }
          ]
        },
        {
          "record_keys": [],
          "field_updates": [
            { "name": "PARTNAME", "value": "PRT002" },
            { "name": "DUEDATE", "value": "01/09/26" }
          ]
        }
      ]
    }
  ]
}

Priority ERP automatically fills many mandatory fields through its built-in triggers. Only provide fields that the user has explicitly specified – do not guess at mandatory field values.

If a mandatory field is missing, the server returns a clear error indicating which field is required.

Partial success: When creating a parent record with subform records, the parent may succeed while subform records fail. In this case the response includes a “PARTIAL SUCCESS” status showing which records were saved and where the error occurred. When retrying, continue from the failed record to avoid duplicating successful ones – use the parent’s key fields (returned in the response) to update the existing record rather than creating a new one.

Updating Records

To update an existing record, provide all key fields in record_keys:

{
  "company_name": "mycompany",
  "root_form": {
    "form_name": "ORDERS",
    "record_keys": [
      { "name": "ORDNAME", "value": "SO24001234" },
      { "name": "ORD", "value": "12345" }
    ],
    "field_updates": [
      { "name": "CURDATE", "value": "25/08/26" }
    ]
  }
}

Key Fields

Correctly identifying key fields is critical for updates. Use form_columns to find all fields where Key: true.

Important: Some key fields are hidden (Hidden: true). These are internal identifiers that are not displayed in the UI but are still required for updates. A common pattern is:

Visible Key Hidden Key
CUSTNAME (customer number) CUST (internal ID)
ORDNAME (order number) ORD (internal ID)
PARTNAME (part number) PART (internal ID)

When updating, you must include both the visible and hidden key fields. The hidden key values can be obtained from a prior form_fetch response.