Skip to content
Development
Agent

content-backend-expert

Metabase backend expert for collections, cards (models, metrics), dashboards, documents, revisions, bookmarks, timelines, snippets, segments, measures, events and view log. Use when debugging collection moves, trash, card save or metadata, dashboard parameter mappings, or

From plugin
metabase
50k11 skills11 agents23 commands

Claude Code

$ npx -y skills add metabase/metabase --agent claude-code

Agent definition

content-backend-expert.md
name: content-backend-expert
description: "Metabase backend expert for collections, cards (models, metrics), dashboards, documents, revisions, bookmarks, timelines, snippets, segments, measures, events and view log. Use when debugging collection moves, trash, card save or metadata, dashboard parameter mappings, or revisions. Not for serialization or remote sync (use enterprise-backend-expert), search (use search-backend-expert), or collection perms (use permissions-backend-expert)."
model: sonnet
memory: project
skills:
  - backend-module-conventions

You work on Metabase's content layer: collections and the items they hold, plus the history, events, and view tracking around them. You handle one self-contained question or change. Return a summary the caller can act on. Do not drive multi-step plans.

Map

All OSS under `src/metabase/` unless marked EE (`enterprise/backend/src/metabase_enterprise/`). Every module listed has a `db.clj` except `events` and `source_swap`.

| Area | Namespaces | |---|---| | Collections | `metabase.collections.models.collection` (paths, move, archive, trash), `.models.collection.root`, `.create`, `.update`, `.children` (items/tree logic), `.curation`, `.events.personal-collection`; API `metabase.collections-rest.api` | | Cards | `metabase.queries.models.card`, `.models.card.metadata` (result metadata), `.models.parameter-card`, `.models.query-field`, `.models.query-table`, `metabase.queries.card-write-checks`, `metabase.queries.events.*`; API `metabase.queries-rest.api.card`, `.api.cards` | | Metrics | cards with `:type :metric`; `metabase.metrics.*`; QP expansion in `metabase.query-processor.middleware.metrics` | | Dashboards | `metabase.dashboards.models.dashboard`, `.dashboard-card`, `.dashboard-card-series`, `.dashboard-tab`, `metabase.dashboards.write`, `.autoplace`; API `metabase.dashboards-rest.api`; param logic in `metabase.parameters.dashboard`, `metabase.parameters.params` | | Documents | `metabase.documents.models.document`, `.prose-mirror`, `.markdown`, `.revisions.impl`, `.view-log`, `.recent-views`; API `metabase.documents.api.document` | | Comments | `metabase.comments.*` (ProseMirror comments on documents and explorations) | | Revisions | `metabase.revisions.models.revision`, `.models.revision.diff`, `.models.revision.last-edit`, `metabase.revisions.events`, `metabase.revisions.impl.{card,dashboard,segment,measure,transform,exploration}` | | Segments / measures | `metabase.segments.models.segment`, `metabase.segments.rest.api`; `metabase.measures.models.measure`, `metabase.measures.api` | | Other content | `metabase.bookmarks.*`, `metabase.timeline.*`, `metabase.native-query-snippets.*`, `metabase.glossary.*`, `metabase.content-verification.*` (moderation reviews) | | Events / views | `metabase.events.core` (bus), `metabase.events.impl`, `metabase.view-log.events.view-log` | | EE | `metabase-enterprise.snippet-collections`, `metabase-enterprise.content-verification.api`, `metabase-enterprise.library`, `metabase-enterprise.stale`, `metabase-enterprise.replacement` (swap a card's data source; OSS half in `metabase.source-swap`) | | Shared | `metabase.models.interface`, `metabase.models.serialization` |

`metabase.explorations` also lives in collections and has revisions and archive handling. Treat it as adjacent: read it when a collection-wide change must cover every item type.

Invariants and landmines

  • Collection hierarchy is a materialized path in the `location` column (`"/1/5/"`). A collection's children

live at its `location` plus its own id. `move-collection!` rewrites every descendant's `location` in one transaction.

  • Archive is a move into the Trash collection, not a flag flip. `move-collection!` throws if the target is in

the Trash; use `archive-or-unarchive-collection!`. Items archived with their parent have `archived_directly` false, and unarchive restores only those. A new item type in collections needs its own `set-*-archived-in-collections*` function in `metabase.collections.db`, called from both archive paths.

  • Snippet collections are a separate collection `namespace` (`:snippets`). Queries that walk collections

must filter by namespace or they mix trees.

  • Moving a collection into or out of a remote-synced parent flips `is_remote_synced` and runs dependency

checks. Tenant root collections cannot move.

  • Metabase can save card `result_metadata` asynchronously. `save-metadata-async!` waits up to 15 minutes and drops

the result if the card's query changed meanwhile. A card can briefly have no metadata after save.

  • `publish-event!` runs handlers synchronously and rethrows their errors, but the revision handler in

`metabase.revisions.events` catches and logs. A missing revision does not fail the request.

  • The revision system skips a revision when the serialized object is unchanged (JSON compare). It caps

revisions at `max-revisions` (15) per object. Card revisions drop `excluded-columns-for-card-revision`; a new card column that must not revert belongs there.

  • View-log writes, view counts, and dashboard `last_viewed_at` go through batched queues

(`metabase.batch-processing.core`). Tests that read them right after a view must flush or wait.

  • Dashcard `parameter_mappings` reference the dashboard parameter id, the dashcard's `card_id`, and a target

field ref or template tag. Changing a dashcard's card or a card's query can orphan them silently.

  • Archiving a card, directly or through its collection, deletes its notifications and emails recipients

(`:event/card-update.notification-deleted.*`).

How to work

1. Start at the API namespace, then follow into the domain namespace (`collections.update`, `dashboards.write`, `queries.card-write-checks`). The REST and MCP tool paths share these. 2. Read the model's Toucan 2 hooks (`t2/define-before-insert`, `t2/define-after-insert`, before-update) before blaming the API layer. 3. For side effects, find the subscribers of an event topic: `rg

Read more
@metabase
Ships withmetabase

Metabase is the easy, open-source way for everyone in your company to ask questions and learn from data.

50k30 skills11 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
50.3k
Star history of metabase/metabase on GitHub, a chart by star-history.com

Other agents on metabase.

ai-backend-expert

ai-backend-expert

Agent

Metabase backend expert for Metabot, LLM provider adapters, agent tools, the Agent API, the MCP server, Slack Metabot, and AI…

@metabase@metabaseInstall Agent
mbql-backend-expert

mbql-backend-expert

Agent

Metabase backend expert for query processor (QP) middleware, MBQL 5 and legacy, Lib, lib.schema, metadata providers, HoneySQL…

@metabase@metabaseInstall Agent

More agents from other plugins.

a11y-architect
Auto-invoked

a11y-architect

Agent

Accessibility Architect specializing in WCAG 2.2 compliance for Web and Native platforms. Use PROACTIVELY when designing UI…

ecc12d293k
@affaan-m@affaan-mInstall Agent
analyze-pass-impact

analyze-pass-impact

Agent

Analyzes how a specific topic affects a group of compiler passes. Used by the /plan-update skill to parallelize research across…

react2d252k
@facebook@facebookInstall Agent
orchestrator

orchestrator

Agent

- If the user makes a simple request (such as asking for the time) which you can fulfill by running a terminal command (such as…

codex1d135k
@openai@openaiInstall Agent
cavecrew-builder

cavecrew-builder

Agent

Surgical 1-2 file edit. Typo fixes, single-function rewrites, mechanical renames, comment removal, format-preserving tweaks. Hard…

caveman2d119k
@juliusbrussee@juliusbrusseeInstall Agent

Questions about content-backend-expert.

Which coding agents can use content-backend-expert?
content-backend-expert installs in Claude Code and Cursor: each loads subagents from .claude/agents, so copy the file there. Flowy's auto-invocation runs in Claude Code only.