Skip to main content
Glama
voducdan

metabase-mcp

by voducdan

update_dashboard_card_position

Reposition or resize a specific card on a Metabase dashboard. Provide the dashboard ID and card ID, then optionally set new column, row, width, or height. Only supplied fields are updated; others remain unchanged.

Instructions

Reposition or resize a single card on a dashboard.

Only the provided fields are updated; omitted fields keep their current values.

Args: dashboard_id: The ID of the dashboard. dashcard_id: The ID of the dashcard (from get_dashboard_cards) to move or resize. col: New column position on the dashboard grid. row: New row position on the dashboard grid. size_x: New width in grid units. size_y: New height in grid units.

Returns: The updated dashboard object.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
dashboard_idYes
dashcard_idYes
colNo
rowNo
size_xNo
size_yNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • Handler function that repositions/resizes a single dashcard on a dashboard by fetching existing dashcards, updating the target dashcard's col/row/size_x/size_y, and PUTting the full dashcards array back to the Metabase API.
    @mcp.tool
    async def update_dashboard_card_position(
        dashboard_id: int,
        dashcard_id: int,
        ctx: Context,
        col: int | None = None,
        row: int | None = None,
        size_x: int | None = None,
        size_y: int | None = None,
    ) -> dict[str, Any]:
        """
        Reposition or resize a single card on a dashboard.
    
        Only the provided fields are updated; omitted fields keep their current values.
    
        Args:
            dashboard_id: The ID of the dashboard.
            dashcard_id: The ID of the dashcard (from get_dashboard_cards) to move or resize.
            col: New column position on the dashboard grid.
            row: New row position on the dashboard grid.
            size_x: New width in grid units.
            size_y: New height in grid units.
    
        Returns:
            The updated dashboard object.
        """
        if col is None and row is None and size_x is None and size_y is None:
            raise ToolError("At least one of col, row, size_x, or size_y must be provided.")
    
        try:
            await ctx.info(
                f"Updating position of dashcard {dashcard_id} on dashboard {dashboard_id}"
            )
    
            dashboard = await metabase_client.request("GET", f"/dashboard/{dashboard_id}")
            existing_dashcards = dashboard.get("dashcards", dashboard.get("ordered_cards", []))
    
            found = False
            dashcards = []
            for dc in existing_dashcards:
                entry = {
                    "id": dc["id"],
                    "card_id": dc.get("card_id"),
                    "row": dc.get("row"),
                    "col": dc.get("col"),
                    "size_x": dc.get("size_x"),
                    "size_y": dc.get("size_y"),
                    "parameter_mappings": list(dc.get("parameter_mappings") or []),
                    "visualization_settings": dc.get("visualization_settings") or {},
                    "inline_parameters": list(dc.get("inline_parameters") or []),
                }
                if dc.get("id") == dashcard_id:
                    found = True
                    if col is not None:
                        entry["col"] = col
                    if row is not None:
                        entry["row"] = row
                    if size_x is not None:
                        entry["size_x"] = size_x
                    if size_y is not None:
                        entry["size_y"] = size_y
                dashcards.append(entry)
    
            if not found:
                raise ToolError(
                    f"Dashcard {dashcard_id} not found on dashboard {dashboard_id}."
                )
    
            result = await metabase_client.request(
                "PUT", f"/dashboard/{dashboard_id}", json={"dashcards": dashcards}
            )
            await ctx.info(
                f"Successfully updated dashcard {dashcard_id} on dashboard {dashboard_id}"
            )
            return result
        except ToolError:
            raise
        except Exception as e:
            error_msg = (
                f"Error updating dashcard {dashcard_id} on dashboard {dashboard_id}: {e}"
            )
            await ctx.error(error_msg)
            raise ToolError(error_msg) from e
  • server.py:1655-1655 (registration)
    Registration via @mcp.tool decorator that registers update_dashboard_card_position as a FastMCP tool.
    @mcp.tool
Behavior3/5

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

No annotations provided. The description explains that omitted fields retain current values, which is a behavioral trait. However, it does not disclose permissions, rate limits, or potential side effects. For a mutation tool, more transparency would be beneficial.

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

Conciseness3/5

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

The description is structured with a clear purpose, then Args and Returns sections. It is somewhat lengthy but not overly verbose. It could be more concise, e.g., by omitting obvious parameter names that match the schema.

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

Completeness4/5

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

Given the presence of an output schema (as per context signals), the description mentions returning the updated dashboard object, which is sufficient. It covers all parameters and behavior for a single card update operation. No gaps identified.

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

Parameters4/5

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

Schema coverage is 0%, but the description includes an Args section that explains all six parameters (dashboard_id, dashcard_id, col, row, size_x, size_y). This adds meaning beyond the schema types and defaults, compensating for the lack of schema descriptions.

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?

The description clearly states 'Reposition or resize a single card on a dashboard.' It uses specific verbs (reposition, resize) and resource (single card, dashboard). This distinguishes from siblings like 'reposition_dashboard_cards' (bulk) and 'add_card_to_dashboard'.

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

Usage Guidelines3/5

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

The description notes that only provided fields are updated, implying partial updates. However, it does not explicitly state when to use this tool over alternatives like 'reposition_dashboard_cards' for bulk operations. No exclusion or prerequisite guidance.

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

Install Server

Other Tools

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/voducdan/matebase-mcp'

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