Lists all the workspace's custom metrics (from an account, its workspace's; up to 50), by name: formula and its readable text, format (number, currency, percent), decimals, whether higher is better, platforms, is_blended (more than one platform: usable in KPIs and charts, not in tables) and who created it (created_by_id, created_by_name). Widgets reference a custom metric by its public_id (custom:<id>).
Scope
dashboards:read
Permission
View the module
MCP tool
dashboards_custom_metrics_listOn the full surface; on the compact one, mb_execute_operation with id: "dashboards.custom_metrics.list".
Declared cost: up to 51 reads and 0 writes per call (they count against the daily quota).
Creates a custom metric in the workspace (not in an account: workspace_only) with a unique name (max 60), optional description, formula, format, decimals (0-4) and higher_is_better. The formula is a tree: {kind: 'metric', metric_id, platform} (a metric id of that platform's registry, numeric), {kind: 'constant', value}, {kind: 'binary', op: '+'|'-'|'*'|'/', left, right} or {kind: 'group', child} (parentheses); up to 20 metrics and 12 levels, never another custom metric. Up to 50 per workspace. Returns the new id; widgets use custom:<id>. Requires edit access to Dashboards in the workspace.
Scope
dashboards:write
Permission
Edit in the module
MCP tool
dashboards_custom_metrics_createOn the full surface; on the compact one, mb_execute_operation with id: "dashboards.custom_metrics.create".
Declared cost: up to 51 reads and 1 writes per call (they count against the daily quota).
Parameters
namestringbodyrequired
A unique name in the workspace (up to 60 characters).
formulaanybodyrequired
The formula, as a tree of nodes (see the operation's description).
Updates any of the name, description (empty clears it), formula, format, decimals and higher_is_better of a workspace custom metric; what is not sent is kept. The formula is a tree: {kind: 'metric', metric_id, platform} (a metric id of that platform's registry, numeric), {kind: 'constant', value}, {kind: 'binary', op: '+'|'-'|'*'|'/', left, right} or {kind: 'group', child} (parentheses); up to 20 metrics and 12 levels, never another custom metric. Every widget that uses it shows the new definition. Returns the updated metric. Requires edit access to Dashboards in the workspace.
Scope
dashboards:write
Permission
Edit in the module
MCP tool
dashboards_custom_metrics_updateOn the full surface; on the compact one, mb_execute_operation with id: "dashboards.custom_metrics.update".
Declared cost: up to 52 reads and 1 writes per call (they count against the daily quota).
Parameters
metric_idstringpathrequired
The custom metric id (dashboards.custom_metrics.list; without the custom: prefix).
namestringbodyoptional
A unique name in the workspace (up to 60 characters).
descriptionstringbodyoptional
A new description (empty clears it).
formulaanybodyoptional
The new formula, as a tree of nodes (see the operation's description).
Deletes a workspace custom metric. It goes to the 30-day trash; widgets and report blocks that use it show an error until it is restored. Outside the screen it requires a dry run and a confirm_token, except a plain REST DELETE with a key allowed to delete. Requires edit access to Dashboards in the workspace.
Instructions for agents
Warn the person that every widget using this metric breaks until it is restored.
With an API key, this DELETE runs directly: the record stays 30 days in the trash and the response carries its trash_item_id. With an OAuth token, and through the MCP, it needs dry_run → confirm_token.
Scope
dashboards:writeand “Allow deletions” (dashboards:delete in OAuth)
Permission
Edit in the module
MCP tool
dashboards_custom_metrics_deleteOn the full surface; on the compact one, mb_execute_operation with id: "dashboards.custom_metrics.delete".
Declared cost: up to 1 reads and 2 writes per call (they count against the daily quota).
Parameters
metric_idstringpathrequired
The custom metric id (dashboards.custom_metrics.list; without the custom: prefix).
Response
oktrue
trash_item_idstring
The trash item this deletion left: the item_id of platform.trash.restore (POST /trash/{item_id}/restore). Missing if nothing went to the trash.
trash_item_idsarray<string>
Only when the deletion left more than one copy: all of them, the first being trash_item_id.
trash_expires_atnumber
When the copy leaves the trash for good (epoch ms): 30 days after the deletion.