add-malli-schemas
Efficiently add Malli schemas to API endpoints in the Metabase codebase with proper patterns, validation timing, and error handling
Dashboard parameters via dashboard_write — add_parameter types and value sources, the wire_parameter target grammar (target_field vs target_tag vs raw target), autowire, linked filters, inline parameters, tab visibility. Read before your first add_parameter or wire_parameter.
$ npx -y skills add metabase/metabase --skill dashboard-filters --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/dashboard-filtersContext preview
The summary Claude sees to decide when to auto-load this skill.
Dashboard parameters via dashboard_write — add_parameter types and value sources, the wire_parameter target grammar (target_field vs target_tag vs raw target), autowire, linked filters, inline parameters, tab visibility. Read before your first add_parameter or wire_parameter.
name: dashboard-filters description: Dashboard parameters via dashboard_write — add_parameter types and value sources, the wire_parameter target grammar (target_field vs target_tag vs raw target), autowire, linked filters, inline parameters, tab visibility. Read before your first add_parameter or wire_parameter. Triggers — "add a filter to this dashboard", "wire a filter to these cards", "make a filter cascade", "filter dropdown values", "why isn't my filter showing / doing anything".
A filter is **a parameter plus a wire per card**: `add_parameter` creates the widget, and it filters nothing until `wire_parameter` connects it to a card — the most common "my filter does nothing" cause. Both are `dashboard_write` ops in one atomic call:
dashboard_write {"method": "update", "id": 40,
"ops": [{"op": "add_parameter", "parameter_id": "category", "name": "Category",
"type": "string/=", "sectionId": "string"},
{"op": "wire_parameter", "parameter_id": "category", "dashcard_id": 7,
"target_field": 18, "autowire": true}]}`parameter_id` is a short slug you choose and reuse in later ops; the server derives the URL slug from `name`. `get_content` on the dashboard lists each parameter's id, type, and wired dashcard ids.
`type`, closed vocabulary: `string/=` `string/!=` `string/contains` `string/does-not-contain` `string/starts-with` `string/ends-with`; `number/=` `number/!=` `number/between` `number/>=` `number/<=`; `date/all-options` (fullest) `date/single` `date/range` `date/relative` `date/month-year` `date/quarter-year`; `category`, `id`, `boolean/=`, `temporal-unit`, `location/city|state|zip_code|country`. `sectionId` groups the widget in the editor: `"string"`, `"number"`, `"date"`, `"id"`, `"location"`, `"temporal-unit"`.
Other `add_parameter`/`update_parameter` fields: `default` (scalar, or array for multi-select), `required` (only with a `default` — without one viewers are blocked until they pick), `isMultiSelect`, `temporal_units` (for `temporal-unit`), `values_query_type` (`"list"` dropdown / `"search"` box / `"none"` free text), `values_source_type` + `values_source_config`, `filteringParameters`. To unset a default or link, name it in `clear` (`"clear": ["default", "filteringParameters"]`) — a null reads as omitted.
| Situation | Pass | |---|---| | Card exposes the column (MBQL card, or a native field-filter tag bound to that field) | `target_field: <field id>` — the usual choice; the server derives the mapping from the card's query | | Native-SQL card, by tag name | `target_tag: "<tag name>"` — the server reads the tag's type (field filter vs variable) and emits the right mapping. Read tag names from the card's `template_tags` via `get_content`; a wrong name's error lists what exists | | `{{placeholder}}` in a text, heading, or iframe card's own content | `target: ["text-tag", "<name>"]` — the name must appear as `{{name}}` in that card | | Neither fits (advanced) | `target: ["dimension", ["template-tag", "category"]]` — the raw clause; hand-built targets are where wiring bugs live |
`autowire: true` (with `target_field`) also maps every other card exposing the same field, silently skipping those that don't; the named `dashcard_id` must expose it or the op fails. A target resolving to nothing on the card is rejected at compile time, on `validate_only` and real saves alike.
`unwire_parameter` disconnects one card (`dashcard_id`) or all (omit it). `remove_parameter` deletes the widget plus its mappings and linked-filter references.
Omit `values_source_type` for live distinct values from the wired column — usually right. Or:
Preview: `get_parameter_values {"target": "dashboard", "id": 40, "parameter_id": "category"}` — also takes `query` (search) and `constraints` (other filters' selections, chain filtering).
A child (City) shows only values consistent with a parent (State) when the child's `filteringParameters` lists the parent's id:
{"op": "update_parameter", "parameter_id": "city", "filteringParameters": ["state"]}Two hard constraints: linked filters read **table-metadata foreign keys only** — joins inside a saved question or model don't count; and a linked child is **incompatible with a `static-list` or `card` source** (a custom source overrides the cascade) — leave it live.
`get_content {"type": "dashboard", "id": 40, "include": ["parameters"]}` — the write response is a skeleton without `default`, `filteringParamet
Metabase is the easy, open-source way for everyone in your company to ask questions and learn from data.
Repo: metabase/metabase
Efficiently add Malli schemas to API endpoints in the Metabase codebase with proper patterns, validation timing, and error handling
Add OpenTelemetry tracing spans to Clojure code following Metabase tracing conventions. Use when instrumenting backend code with trace coverage.
Add product analytics events to track user interactions in the Metabase frontend
Evaluate Clojure code via nREPL using clj-nrepl-eval. Use this when you need to test code, check if edited files compile, verify function behavior, or interact…
Review Clojure and ClojureScript code changes for compliance with Metabase coding standards, style violations, and code quality issues. Use when reviewing pull…
Guide Clojure and ClojureScript development using REPL-driven workflow, coding conventions, and best practices. Use when writing, developing, or refactoring…