KasarKasar Docs
MCP Server

Tools — Data model

Create custom objects, fields, and lists, and edit enum options from the data model. Admin only. Deletion is intentionally not exposed.

Four tools to build and edit the data model programmatically: create an object, add fields (batch), create a list, and edit the options of a SELECT / MULTI_SELECT field. All four are admin only and execute immediately (the API token is the authorization — there is no preview step for object/field/list creation).

Data-model deletion is never exposed via MCP (or the AI agent). Removing an object or a field — deactivation or hard delete — is done manually in the app. There is intentionally no crm_delete_object / crm_delete_field tool. This is a safety boundary, not an omission. (A list can be deleted, admin-only, via crm_manage_lists with action: "delete" — see Tools — Data.)

These tools wrap the same server-side actions the app uses, so validation, multi-tenant isolation, metadata cache invalidation, and real-time propagation are identical to creating from the UI.

crm_create_field was renamed to crm_create_fields and is now a batch tool: it creates one or many fields in a single atomic migration. There is no single-field tool anymore.


crm_create_object

Create a new custom object. The object and table names are derived from the labels. You can optionally pass fields to create the object with its initial fields in one atomic migration; otherwise add fields later with crm_create_fields.

Parameters

ParameterTypeRequiredDescription
label_singularstringYesSingular display label, e.g. Produit
label_pluralstringYesPlural display label, e.g. Produits
descriptionstringNoObject description
icon_namestringNoLucide icon name (e.g. Box)
colorstringNoHex color, e.g. #6366F1
fieldsobject[]NoOptional initial custom fields, created atomically with the object. Same per-field shape as crm_create_fields (see field spec).

Behavior

  • The object is created with the base fields and a name standard field (the immutable first column).
  • The derived name_plural is returned as name_plural — use it as object_name in crm_create_fields and the data tools.
  • When fields is provided, the object and all its fields are created in a single all-or-nothing migration; the response includes created_fields.
  • Labels that slugify to empty (blank, or symbol/digit-only like !!!) return INVALID_ARGUMENT.
  • Fails with DUPLICATE_OBJECT if an object with the derived name already exists.

Examples

"Create a Products object"

{
  "label_singular": "Produit",
  "label_plural": "Produits"
}

"Create a Products object with a Price and a Stock field in one go"

{
  "label_singular": "Produit",
  "label_plural": "Produits",
  "icon_name": "Box",
  "color": "#6366F1",
  "fields": [
    { "field_label": "Price", "field_type": "CURRENCY" },
    { "field_label": "Stock", "field_type": "INTEGER" }
  ]
}

Response shape:

{
  "name_plural": "produits",
  "name_singular": "produit",
  "created_fields": [
    { "field_name": "price", "field_type": "CURRENCY" },
    { "field_name": "stock", "field_type": "INTEGER" }
  ],
  "action": "created"
}

crm_create_fields

Add one or many fields to an existing object in a single atomic call — every field is created in one migration (all-or-nothing). object_name may target a list_* object to add per-entry fields to a list.

Parameters

ParameterTypeRequiredDescription
object_namestringYesTarget object (name_plural). May be a list_* object.
fieldsobject[]YesFields to create — at least one (see field spec).

Field spec

Each entry in fields (also used by crm_create_object.fields):

ParameterTypeRequiredDescription
field_labelstringYesDisplay label; the field name is derived from it.
field_typeenumYesSee supported types below.
descriptionstringNoField description
is_requiredbooleanNoDefault false
is_searchablebooleanNoDefault true
optionsobject[]Cond.{ value, label, color? }required for SELECT / MULTI_SELECT. This is the field's initial set; to edit options on an existing field use crm_manage_enum_options.
relation_configobjectCond.Required for RELATION (see below).

relation_config (for RELATION):

KeyTypeRequiredDescription
relation_typeenumYesBELONGS_TO_ONE, HAS_MANY, or ONE_TO_ONE
target_objectstringYesTarget object name (name_plural)
target_field_labelstringNoLabel for the auto-created inverse field

Supported field types

crm_create_fields (and crm_create_object.fields) accept the batch-creatable set (BATCH_FIELD_TYPES):

TEXT, LONG_TEXT, RICH_TEXT, EMAIL, PHONE, URL, NUMBER, INTEGER, DECIMAL, PERCENT, CURRENCY, DATE, DATETIME, DURATION, BOOLEAN, SELECT, MULTI_SELECT, RELATION, DATE_RANGE, DATETIME_RANGE, USERS, EMAILS, PHONES, ADDRESS, DOCUMENTS, JSON, COLOR, RATING, IMAGE.

Types that need bespoke configuration or a dedicated action are not creatable here and are managed in the app: CALCULATED, ROLLUP, EXTERNAL_LOOKUP, ELAPSED_TIME, PIPELINE, MANY_TO_MANY, MORPH_RELATION, DEPENDENT_RELATION.

Behavior

  • SELECT / MULTI_SELECT require a non-empty options array; RELATION requires relation_config.target_object. Invalid specs reject the whole batch before any DDL with INVALID_FIELDS (the error carries the allowed types in available_values).
  • Field names are derived from labels; a collision within the batch, or with an existing field on the object, is rejected (INVALID_FIELDS / DUPLICATE_FIELD) — nothing is silently skipped.
  • Returns INVALID_OBJECT if object_name does not exist (the error lists available objects).
  • The response reports created (the created fields), count, and action: "created".

Examples

"Add a Stage field to opportunities with options Lead / Won / Lost"

{
  "object_name": "opportunities",
  "fields": [
    {
      "field_label": "Stage",
      "field_type": "SELECT",
      "options": [
        { "value": "lead", "label": "Lead" },
        { "value": "won", "label": "Won", "color": "#16A34A" },
        { "value": "lost", "label": "Lost", "color": "#DC2626" }
      ]
    }
  ]
}

"Add Price, Stock and a Supplier link to products in one migration"

{
  "object_name": "produits",
  "fields": [
    { "field_label": "Price", "field_type": "CURRENCY" },
    { "field_label": "Stock", "field_type": "INTEGER" },
    {
      "field_label": "Supplier",
      "field_type": "RELATION",
      "relation_config": {
        "relation_type": "BELONGS_TO_ONE",
        "target_object": "companies",
        "target_field_label": "Products supplied"
      }
    }
  ]
}

"Add a per-entry Priority field to a list"

{
  "object_name": "list_investors",
  "fields": [
    { "field_label": "Priority", "field_type": "NUMBER" }
  ]
}

Response shape:

{
  "object_name": "produits",
  "created": [
    { "field_name": "price", "field_type": "CURRENCY" },
    { "field_name": "stock", "field_type": "INTEGER" },
    { "field_name": "supplier", "field_type": "RELATION" }
  ],
  "count": 3,
  "action": "created"
}

crm_create_list

Create a multi-object list — a cross-object collection of records. Entries are managed afterwards with crm_manage_lists.

Parameters

ParameterTypeRequiredDescription
namestringYesList display name (must be unique)
allowed_objectsstring[]YesObject names (name_plural) whose records can be added — at least one
descriptionstringNoList description
icon_namestringNoLucide icon name (default List)
colorstringNoHex color

Behavior

  • A list is materialized as a hidden list_<slug> object holding one entry row per added record.
  • allowed_objects are filtered to the objects the caller can view. The response reports the effective allowed_objects and, when any were silently dropped (not visible to the caller), a dropped_objects array — so a partial result is detectable.
  • If none of the requested objects are visible / valid, the call fails with INVALID_LIST.
  • Returns list_id and entry_object_name (the list_* object you can target with crm_create_fields).

Examples

"Create an Investors list for companies and contacts"

{
  "name": "Investors",
  "allowed_objects": ["companies", "contacts"]
}

Response shape (one object was not visible to the caller and was dropped):

{
  "list_id": "a1b2c3d4-...",
  "entry_object_name": "list_investors",
  "allowed_objects": ["companies"],
  "dropped_objects": ["contacts"],
  "action": "created"
}

crm_manage_enum_options

Edit the options of an existing SELECT / MULTI_SELECT field: append new options, relabel/recolor existing ones, and/or remove options. Works on system fields too (options are stored inline per field). Use this to change a field's options after creation — crm_create_fields only sets the initial set.

Parameters

ParameterTypeRequiredDescription
object_namestringYesObject (name_plural) owning the field. May be a list_* object.
field_namestringYesThe SELECT / MULTI_SELECT field name (not the label).
previewbooleanNoRead-only: return each option with its record usage count (no mutation). Use this before a destructive remove.
addobject[]NoOptions to append: { value, label, color? }. value is snake_case, lowercase ASCII, unique within the field.
relabelobject[]NoLabel/color edits on existing options: { value, label?, color? }. color: null clears the color. Never touches data.
removestring[]NoOption values to delete.
remappingobjectCond.Required when remove is set. A map { removedValue: targetValue | null } covering every removed value in use — either move records to another value, or null to clear the field on those records.

You must provide at least one of add, relabel, remove, or preview; otherwise the call returns INVALID_PARAMS.

Behavior

  • preview: true returns the field's current options plus a per-value usage count and performs no mutation — use it to build a complete, safe remapping.
  • Removing an option always deletes it from the field definition. Any record still using a removed value is remapped per remapping; an incomplete remapping is rejected so no record is ever orphaned.
  • The response reports removed_options (the values deleted) and remapped_records (the number of rows moved) separately — a remapped_records of 0 does not mean the option was kept (it had no records in use).
  • Fails with INVALID_FIELD if the field doesn't exist or is not SELECT / MULTI_SELECT, and INVALID_OBJECT if the object doesn't exist.

Option removal is the only destructive action in this group. Always call with preview: true first to see usage counts, then build a complete remapping before removing.

Examples

"What are the options on opportunities' Stage field, and how many deals use each?"

{
  "object_name": "opportunities",
  "field_name": "stage",
  "preview": true
}

"Add a 'Negotiation' option and recolor 'Won' green on the Stage field"

{
  "object_name": "opportunities",
  "field_name": "stage",
  "add": [
    { "value": "negotiation", "label": "Negotiation", "color": "#F59E0B" }
  ],
  "relabel": [
    { "value": "won", "label": "Won", "color": "#16A34A" }
  ]
}

"Remove the 'lost' option, moving its deals to 'closed'"

{
  "object_name": "opportunities",
  "field_name": "stage",
  "remove": ["lost"],
  "remapping": { "lost": "closed" }
}

Response shape:

{
  "object_name": "opportunities",
  "field_name": "stage",
  "removed_options": ["lost"],
  "remapped_records": 12,
  "action": "updated"
}

Errors

CodeDescription
PERMISSION_DENIEDThe token is not an organization admin. Data-model changes are admin only.
INVALID_ARGUMENTLabels derive an empty object name (blank or symbol/digit-only).
DUPLICATE_OBJECTAn object with the derived name already exists.
INVALID_OBJECTobject_name does not exist (the error lists available objects).
INVALID_FIELDSA field spec is invalid (e.g. SELECT without options, RELATION without target_object) or uses an unsupported field_type (the error lists allowed types).
DUPLICATE_FIELDA field with the derived name already exists on the object (or collides within the batch).
INVALID_FIELDFor crm_manage_enum_options: the field doesn't exist or is not SELECT / MULTI_SELECT.
INVALID_PARAMSFor crm_manage_enum_options: none of add / relabel / remove / preview was provided.
INVALID_LISTThe list has no allowed objects, or none the caller can view.
CREATE_OBJECT_FAILED / CREATE_FIELDS_FAILED / CREATE_LIST_FAILED / MANAGE_ENUM_FAILEDThe underlying migration failed; the message carries the cause.

On this page