@metabase/cli 0.1.2 → 0.1.4-alpha.skill-packaging.1c8ec40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. package/.claude-plugin/marketplace.json +19 -0
  2. package/README.md +467 -388
  3. package/dist/add-collection-B3NhkLRT.mjs +11 -0
  4. package/dist/{add-collection-DwxQDXzL.mjs → add-collection-CEvZTea_.mjs} +5 -5
  5. package/dist/{api-key-BktzvPb7.mjs → api-key-BpmnzLLb.mjs} +1 -1
  6. package/dist/{archive-CLWtbvvH.mjs → archive-BPLLOdfL.mjs} +7 -7
  7. package/dist/{archive-C1mF-9Kj.mjs → archive-CazAWIrV.mjs} +6 -6
  8. package/dist/{archive-kYoy5LK5.mjs → archive-D596Cq7R.mjs} +7 -7
  9. package/dist/{archive-Cq4WKmJt.mjs → archive-DqPqXMZm.mjs} +7 -7
  10. package/dist/auth-DJp4QoWI.mjs +19 -0
  11. package/dist/{body-rDrR-C1c.mjs → body-CVSMGqZk.mjs} +3 -3
  12. package/dist/{branches-CH2UcCpX.mjs → branches--TavvEK1.mjs} +7 -7
  13. package/dist/{cancel-CgLZcItQ.mjs → cancel-BUitag4_.mjs} +6 -6
  14. package/dist/{cancel-task-DcYrFsM6.mjs → cancel-task-BHcWJUMu.mjs} +7 -7
  15. package/dist/card-DtUIadDM.mjs +20 -0
  16. package/dist/{cards-C4NIaERo.mjs → cards-Bir6wRS_.mjs} +6 -6
  17. package/dist/cli.mjs +31 -27
  18. package/dist/collection-4-gZeCWg.mjs +19 -0
  19. package/dist/{create-CNvd5T8h.mjs → create-4OjxTGAe.mjs} +10 -10
  20. package/dist/{create-bqc_rmix.mjs → create-BISpvrml.mjs} +10 -10
  21. package/dist/{create-BUCLNqiN.mjs → create-Bi8sqzL-.mjs} +13 -13
  22. package/dist/{create-Cbh1cGj9.mjs → create-C1cdoSw5.mjs} +12 -12
  23. package/dist/{create-Dh0p-c2Y.mjs → create-C3TiMJhQ.mjs} +10 -10
  24. package/dist/{create-QgN369N5.mjs → create-CZZc1KM8.mjs} +13 -13
  25. package/dist/{create-DU0ZhnZu.mjs → create-CxMpPsRO.mjs} +9 -9
  26. package/dist/{create-CB0Yp__0.mjs → create-Dj-fO-nV.mjs} +12 -12
  27. package/dist/{create-DvrVZ2hS.mjs → create-DuyWlx-S.mjs} +11 -11
  28. package/dist/{create-branch-BJFH9Hda.mjs → create-branch-CH1FmnxS.mjs} +7 -7
  29. package/dist/{create-CzfNOhOF.mjs → create-hYdLOyw_.mjs} +12 -12
  30. package/dist/{credentials-DTP1xuKz.mjs → credentials-BARfQeBr.mjs} +11 -9
  31. package/dist/{current-task-z_TiJ0kt.mjs → current-task-TX7rJmon.mjs} +7 -7
  32. package/dist/dashboard-C-azCGk-.mjs +20 -0
  33. package/dist/{database-DQkUxTLd.mjs → database-BKfGtTmB.mjs} +3 -3
  34. package/dist/db-D--IArxI.mjs +22 -0
  35. package/dist/{delete-DeZQ1r9w.mjs → delete-BxUaF8kW.mjs} +8 -8
  36. package/dist/{delete-CVYII8mq.mjs → delete-DzTd5w_y.mjs} +8 -8
  37. package/dist/{delete-runtime-BMzvfj_B.mjs → delete-runtime-DfFMWJJ6.mjs} +2 -2
  38. package/dist/{delete-table-ZiR9-ndv.mjs → delete-table-DWfA7uVn.mjs} +8 -8
  39. package/dist/{deprovision-BhD3J-Am.mjs → deprovision-CadXjs_7.mjs} +12 -12
  40. package/dist/{dirty-D9agt7Os.mjs → dirty-an-DQtBG.mjs} +7 -7
  41. package/dist/{docker-CHpV8PRz.mjs → docker-C9WQCjkt.mjs} +6 -103
  42. package/dist/{eid-B5wawMmO.mjs → eid-Cz9r5RX5.mjs} +1 -1
  43. package/dist/{export-Bfk7JAlR.mjs → export-BHq8ztFL.mjs} +10 -10
  44. package/dist/field-Do1HcUfq.mjs +18 -0
  45. package/dist/{fields-7ByLsxLg.mjs → fields-B21DeL2I.mjs} +6 -6
  46. package/dist/{flag-pair-DtR1AiBQ.mjs → flag-pair-Fmcdkrfx.mjs} +1 -1
  47. package/dist/{get-DikegGzi.mjs → get-BAqeeIQ-.mjs} +6 -6
  48. package/dist/{get-tISo-cmg.mjs → get-BHCgwPPT.mjs} +9 -9
  49. package/dist/{get-CQGeF-eP.mjs → get-BPah4iYM.mjs} +6 -6
  50. package/dist/{get-DKy3DAJX.mjs → get-C4_7ZrIS.mjs} +7 -7
  51. package/dist/{get-cuHp9-6U.mjs → get-CAYnc9sd.mjs} +6 -6
  52. package/dist/{get-BE6Izpus.mjs → get-ChEFd1sT.mjs} +7 -7
  53. package/dist/{get-gOT_RarI.mjs → get-ChxcxY2D.mjs} +7 -7
  54. package/dist/{get-DUSR5i99.mjs → get-Cy9YIesM.mjs} +6 -6
  55. package/dist/{get-bYc7eGYe.mjs → get-D-zU7VmK.mjs} +6 -6
  56. package/dist/{get-D2m4jhwT.mjs → get-DFm7pR7F.mjs} +8 -8
  57. package/dist/get-DWttywn_.mjs +79 -0
  58. package/dist/{get-StkjKuh0.mjs → get-RPL4h0It.mjs} +8 -8
  59. package/dist/{get-C3CcAJGg.mjs → get-dqrzLuwA.mjs} +8 -8
  60. package/dist/{get-run-D59Yqaoh.mjs → get-run-CG3QFs9T.mjs} +7 -7
  61. package/dist/git-sync-COKsdLkS.mjs +28 -0
  62. package/dist/{has-remote-changes-B1TciDVD.mjs → has-remote-changes-ecra9BFO.mjs} +7 -7
  63. package/dist/{import-DnnmmJbp.mjs → import-BzOKkYnp.mjs} +10 -10
  64. package/dist/{input-ikCiip6x.mjs → input-BQ-BZA8h.mjs} +1 -1
  65. package/dist/{is-dirty-DlfX7e39.mjs → is-dirty-7afLBOtn.mjs} +4 -4
  66. package/dist/is-dirty-Dnw0AHFw.mjs +10 -0
  67. package/dist/{items-DQFQSpjF.mjs → items-BEWSuEfe.mjs} +10 -10
  68. package/dist/{key-NDEARu2L.mjs → key-CCJdVWKc.mjs} +1 -1
  69. package/dist/{license-DBh13sc8.mjs → license-D3mFdxAq.mjs} +3 -3
  70. package/dist/{list-DQj-QJAs.mjs → list-B5E7LFDb.mjs} +8 -8
  71. package/dist/{list-BwjqQ6pp.mjs → list-B9mEqMZ5.mjs} +5 -5
  72. package/dist/{list-D067ZSE5.mjs → list-BJAC356Q.mjs} +7 -7
  73. package/dist/{list-Di529OJD.mjs → list-BOQWvb8b.mjs} +5 -5
  74. package/dist/{list-Cy0VhXQs.mjs → list-BZFTuiBr.mjs} +6 -6
  75. package/dist/{list-DJN-OvTZ.mjs → list-By3t67Y8.mjs} +7 -7
  76. package/dist/{list-GFfR9SuT.mjs → list-ByPzCM2G.mjs} +5 -5
  77. package/dist/{list-9AOWhxqp.mjs → list-C8b-KxY6.mjs} +8 -8
  78. package/dist/{list-iFVEdi2J.mjs → list-CiHlWufc.mjs} +6 -6
  79. package/dist/{list-DlKzgnqo.mjs → list-D_exD3LP.mjs} +7 -7
  80. package/dist/{list-4kYCGv01.mjs → list-DiAyv9l3.mjs} +6 -6
  81. package/dist/{list-CP5RNjO6.mjs → list-DtSOfMZ2.mjs} +6 -6
  82. package/dist/list-DwF6on6O.mjs +44 -0
  83. package/dist/{list-DAZP-IM5.mjs → list-nIxzXqr-.mjs} +5 -5
  84. package/dist/{login-DxgkosGx.mjs → login-Cka2HZWz.mjs} +9 -9
  85. package/dist/{logout-BlVwqBog.mjs → logout-rA25M-oa.mjs} +6 -6
  86. package/dist/{logs-CudNEkT4.mjs → logs-B5cGXoDi.mjs} +11 -10
  87. package/dist/{manifest-Dv5B9Blc.mjs → manifest-CGM7XNLC.mjs} +2 -2
  88. package/dist/measure-CwJ2o89T.mjs +19 -0
  89. package/dist/{metadata-BTJAFVvZ.mjs → metadata-BEd6s_Qf.mjs} +6 -6
  90. package/dist/{metadata-B2Td415K.mjs → metadata-DirWO0cS.mjs} +6 -6
  91. package/dist/{package-DV6Asqim.mjs → package-VV3qWWIQ.mjs} +10 -3
  92. package/dist/{parse-id-B38zTlYs.mjs → parse-id-DbSjfzoU.mjs} +1 -1
  93. package/dist/{parse-ref-DGvh4aDn.mjs → parse-ref-D1yeDOn8.mjs} +1 -1
  94. package/dist/{parse-schemas-Ds-cVE-O.mjs → parse-schemas-BXTlpoaf.mjs} +2 -2
  95. package/dist/path-DarsuSkB.mjs +58 -0
  96. package/dist/{poll-Bh6oAifO.mjs → poll-Cd8bRMmZ.mjs} +2 -2
  97. package/dist/{poll-task-vPwV31Fs.mjs → poll-task-BwKuhZ9P.mjs} +2 -2
  98. package/dist/{predicates-DiIiS3k7.mjs → predicates-CGO17Q15.mjs} +1 -1
  99. package/dist/{preflight-DxJb-hUV.mjs → preflight-RkDLqtNm.mjs} +3 -3
  100. package/dist/process-zJeVJZTM.mjs +105 -0
  101. package/dist/{prompt-Bf3DQ-qE.mjs → prompt-DgDNy_Pc.mjs} +1 -1
  102. package/dist/{provision-B-I0zuDe.mjs → provision-DBqPA-De.mjs} +15 -15
  103. package/dist/{ps-CaiOFCv2.mjs → ps-Cn3lzak-.mjs} +4 -4
  104. package/dist/ps-DIm7IScc.mjs +11 -0
  105. package/dist/{query-BtF1yWZZ.mjs → query-BoOismbH.mjs} +13 -13
  106. package/dist/{query-jmfqaXRP.mjs → query-CkNa5Nam.mjs} +9 -9
  107. package/dist/{remove-xskleeru.mjs → remove-B7NUBOqF.mjs} +6 -6
  108. package/dist/{remove-C2iv0g03.mjs → remove-C08c3vne.mjs} +10 -9
  109. package/dist/{remove-collection-DhZghaZy.mjs → remove-collection-cFO9M-qV.mjs} +9 -9
  110. package/dist/{render-DXv-D6fU.mjs → render-DuoDUTVL.mjs} +1 -1
  111. package/dist/{rescan-values-DW6u90ep.mjs → rescan-values-D1-IyyU7.mjs} +6 -6
  112. package/dist/{revision-message-flag-CWQbKhdl.mjs → revision-message-flag-oyq2xrDU.mjs} +1 -1
  113. package/dist/{run-DxVzhcF3.mjs → run-BCzKf_TV.mjs} +9 -9
  114. package/dist/{runs-BOHk1XnM.mjs → runs-pVgTv7cK.mjs} +9 -9
  115. package/dist/{runtime-cwBS8wwK.mjs → runtime-DPdP0sl1.mjs} +6 -6
  116. package/dist/{schema-tables-CcFbY_jN.mjs → schema-tables-c6K9AkS-.mjs} +6 -6
  117. package/dist/{schemas-DZmv_V62.mjs → schemas-s3PRMTwc.mjs} +6 -6
  118. package/dist/{search-CYMuc7Fg.mjs → search-DsF08cm9.mjs} +8 -8
  119. package/dist/segment-CvPF5gLG.mjs +19 -0
  120. package/dist/{set-CbGfQ7Ye.mjs → set-BNQjt8S1.mjs} +12 -12
  121. package/dist/{set-B_rrVwU4.mjs → set-DlfevPxG.mjs} +9 -9
  122. package/dist/{setting-DqZY9NXP.mjs → setting-Cc5FWSNN.mjs} +3 -3
  123. package/dist/{setup-DxmcAorA.mjs → setup-CIsvZgEA.mjs} +9 -9
  124. package/dist/skills-CHU7uuDU.mjs +191 -0
  125. package/dist/skills-Dws-azxD.mjs +18 -0
  126. package/dist/snippet-W-TaXdio.mjs +19 -0
  127. package/dist/{start-Cn0epTks.mjs → start-xREv6hev.mjs} +19 -17
  128. package/dist/{stash-BFZIl9F4.mjs → stash-ZLbOejYk.mjs} +9 -9
  129. package/dist/{status-UALK3OJl.mjs → status-CYWbB67d.mjs} +5 -5
  130. package/dist/{status-FDIDmqvM.mjs → status-DiXaGNmb.mjs} +5 -5
  131. package/dist/{status-BjCeJNLp.mjs → status-DjRAgzXl.mjs} +8 -8
  132. package/dist/{stop-DUwrDWw8.mjs → stop-CWKn_jI8.mjs} +10 -9
  133. package/dist/{summary-CS4UGiFJ.mjs → summary-CIFwiame.mjs} +6 -6
  134. package/dist/{sync-schema-IrHdJxmX.mjs → sync-schema-_SRMfBSQ.mjs} +6 -6
  135. package/dist/table-uhBlfNYj.mjs +19 -0
  136. package/dist/transform-UJ7T_BSb.mjs +24 -0
  137. package/dist/transform-job-DXs5apQ1.mjs +19 -0
  138. package/dist/{translate-B__zbDKm.mjs → translate-DVN_sIVb.mjs} +10 -10
  139. package/dist/{tree-Mh0uQ_Wy.mjs → tree-BTZfgldu.mjs} +5 -5
  140. package/dist/{update-D2VI_5cy.mjs → update-Bjd7YRyh.mjs} +13 -13
  141. package/dist/{update-Bw0WZix_.mjs → update-CCFegz4q.mjs} +15 -15
  142. package/dist/{update-BfBsM_y1.mjs → update-CDdML0mE.mjs} +14 -14
  143. package/dist/{update-B9DBMo30.mjs → update-CGYM_wWQ.mjs} +12 -12
  144. package/dist/{update-Cp1789qq.mjs → update-CYMsVUQX.mjs} +10 -10
  145. package/dist/{update-j9vgemKR.mjs → update-D48EYMKn.mjs} +10 -10
  146. package/dist/{update-1Di9hbPo.mjs → update-D6jptFDw.mjs} +14 -14
  147. package/dist/{update-B5_pp6Jj.mjs → update-DSjj9UQb.mjs} +15 -15
  148. package/dist/{update-Masp5WeT.mjs → update-DjfNbEgo.mjs} +11 -11
  149. package/dist/{update-D8GwQTcL.mjs → update-ZRF-sYqN.mjs} +16 -16
  150. package/dist/{update-dashcard-CNiQw1MD.mjs → update-dashcard-BfcB6pFx.mjs} +10 -10
  151. package/dist/upgrade-Cw_mP31_.mjs +432 -0
  152. package/dist/{url-GFM76VIK.mjs → url-DsDSVEnK.mjs} +9 -8
  153. package/dist/{uuid-Uif0lNk8.mjs → uuid-DbtHyH33.mjs} +7 -7
  154. package/dist/{validate-DCYx6jdL.mjs → validate-CB0bu50i.mjs} +3 -3
  155. package/dist/{validate-query-B07oGG4K.mjs → validate-query-CavIA0Q2.mjs} +3 -3
  156. package/dist/{values-DrwNHUAI.mjs → values-C1JRC3O2.mjs} +6 -6
  157. package/dist/{wait-DO7tS7NI.mjs → wait-Ed4Q7ccW.mjs} +2 -2
  158. package/dist/{wait-BoKk8CJy.mjs → wait-LRmiGepb.mjs} +8 -8
  159. package/dist/{wait-flags-CjX2sEGm.mjs → wait-flags-pItBfuzi.mjs} +2 -2
  160. package/dist/workspace-BozpZKez.mjs +24 -0
  161. package/dist/{workspace-credentials-B6BL-X0d.mjs → workspace-credentials-4lIxxz4g.mjs} +2 -41
  162. package/dist/yaml-ECiog374.mjs +43 -0
  163. package/package.json +8 -3
  164. package/skill-data/core/SKILL.md +575 -0
  165. package/skill-data/git-sync/SKILL.md +196 -0
  166. package/skill-data/transform/SKILL.md +235 -0
  167. package/skill-data/workspace/SKILL.md +408 -0
  168. package/skills/metabase-cli/SKILL.md +42 -0
  169. package/dist/add-collection-SL08iMub.mjs +0 -11
  170. package/dist/auth-DfYkakP3.mjs +0 -19
  171. package/dist/card-ZCGU2JEh.mjs +0 -20
  172. package/dist/collection-D_uFLIAS.mjs +0 -19
  173. package/dist/dashboard-G1-dGLUR.mjs +0 -20
  174. package/dist/db-CBaEfumR.mjs +0 -22
  175. package/dist/field-BDJ1pEgr.mjs +0 -18
  176. package/dist/git-sync-BiTWfLgY.mjs +0 -28
  177. package/dist/is-dirty-DClGFOGV.mjs +0 -10
  178. package/dist/measure-C7SbdYQk.mjs +0 -19
  179. package/dist/ps-BmYQYC7t.mjs +0 -10
  180. package/dist/segment-Df4pfjco.mjs +0 -19
  181. package/dist/snippet-CwSHjQyn.mjs +0 -19
  182. package/dist/table-Cdr5bKp1.mjs +0 -19
  183. package/dist/transform-CeZusR_w.mjs +0 -24
  184. package/dist/transform-job-BOn9-CGa.mjs +0 -19
  185. package/dist/workspace-CyEX40D-.mjs +0 -24
  186. /package/dist/{snippet-Dw0Sjzkr.mjs → snippet-CSWqkslB.mjs} +0 -0
  187. /package/dist/{transform-IEX4Mx3X.mjs → transform-DR4ejuPM.mjs} +0 -0
  188. /package/dist/{transform-job-Csr86muI.mjs → transform-job-BrhOLO4M.mjs} +0 -0
  189. /package/dist/{workspace-DVuqKJGG.mjs → workspace-DUfqhPm5.mjs} +0 -0
package/README.md CHANGED
@@ -6,7 +6,7 @@ Command-line client for Metabase. Authenticates against an instance with an API
6
6
 
7
7
  ```sh
8
8
  npm install -g @metabase/cli
9
- metabase --help
9
+ mb --help
10
10
  ```
11
11
 
12
12
  Or build from source:
@@ -17,20 +17,20 @@ bun run build
17
17
  node dist/cli.mjs --help
18
18
  ```
19
19
 
20
- The binary is `metabase`. Examples below use that name.
20
+ The binary is `mb`. Examples below use that name.
21
21
 
22
22
  ## Quick start
23
23
 
24
24
  ```sh
25
- metabase auth login --url https://metabase.example.com
26
- metabase auth status
25
+ mb auth login --url https://metabase.example.com
26
+ mb auth status
27
27
  ```
28
28
 
29
29
  ## Authentication
30
30
 
31
31
  Credentials are stored per-profile. The default profile is named `default`. Use `--profile <name>` to manage additional profiles.
32
32
 
33
- ### `metabase auth login`
33
+ ### `mb auth login`
34
34
 
35
35
  Save credentials for a profile.
36
36
 
@@ -44,18 +44,18 @@ Save credentials for a profile.
44
44
  Resolution order for the API key: `--api-key` → piped stdin → `METABASE_API_KEY` → interactive prompt. Stdin is auto-detected when not a TTY.
45
45
 
46
46
  ```sh
47
- echo "$MB_KEY" | metabase auth login --url https://m.example.com
48
- metabase auth login --url https://m.example.com < key.txt
47
+ echo "$MB_KEY" | mb auth login --url https://m.example.com
48
+ mb auth login --url https://m.example.com < key.txt
49
49
  ```
50
50
 
51
- ### `metabase auth status`
51
+ ### `mb auth status`
52
52
 
53
53
  Show whether a profile is authenticated.
54
54
 
55
55
  ```sh
56
- metabase auth status
57
- metabase auth status --json
58
- metabase auth status --profile staging
56
+ mb auth status
57
+ mb auth status --json
58
+ mb auth status --profile staging
59
59
  ```
60
60
 
61
61
  | Flag | Description |
@@ -63,26 +63,26 @@ metabase auth status --profile staging
63
63
  | `--profile <name>` | Profile to inspect (default: `default`). |
64
64
  | `--json` | Emit JSON. Auto-enabled on non-TTY. |
65
65
 
66
- ### `metabase auth list`
66
+ ### `mb auth list`
67
67
 
68
68
  List configured authentication profiles. The index is maintained at `<configDir>/profiles.json` and updated on every `auth login` / `auth logout`. Profiles whose URL/API key were stored in the OS keychain before the index existed are picked up by a one-time backfill from `credentials.json`; profiles that exist only in the keyring (no entry in `credentials.json`) appear after the next `auth login` or `auth logout` against them.
69
69
 
70
70
  ```sh
71
- metabase auth list
72
- metabase auth list --json
71
+ mb auth list
72
+ mb auth list --json
73
73
  ```
74
74
 
75
75
  | Flag | Description |
76
76
  | -------- | ----------------------------------- |
77
77
  | `--json` | Emit JSON. Auto-enabled on non-TTY. |
78
78
 
79
- ### `metabase auth logout`
79
+ ### `mb auth logout`
80
80
 
81
81
  Clear stored credentials for a profile.
82
82
 
83
83
  ```sh
84
- metabase auth logout --yes
85
- metabase auth logout --profile staging --yes
84
+ mb auth logout --yes
85
+ mb auth logout --profile staging --yes
86
86
  ```
87
87
 
88
88
  | Flag | Description |
@@ -94,36 +94,36 @@ metabase auth logout --profile staging --yes
94
94
 
95
95
  Manage the Metabase Enterprise license token.
96
96
 
97
- ### `metabase license set [token]`
97
+ ### `mb license set [token]`
98
98
 
99
99
  Store a license token. Resolution order: positional → piped stdin → `METABASE_LICENSE_TOKEN` → interactive prompt. Stdin is auto-detected when not a TTY.
100
100
 
101
101
  Common output flags (`--json`, `--format`, `--detail`, `--fields`, `--max-bytes`) are accepted; the result payload is rendered through the standard output layer.
102
102
 
103
103
  ```sh
104
- echo "$MB_LICENSE" | metabase license set
105
- metabase license set < token.txt
104
+ echo "$MB_LICENSE" | mb license set
105
+ mb license set < token.txt
106
106
  ```
107
107
 
108
- ### `metabase license status`
108
+ ### `mb license status`
109
109
 
110
110
  Show whether a license is stored. Does not reveal the value.
111
111
 
112
112
  ```sh
113
- metabase license status
114
- metabase license status --json
113
+ mb license status
114
+ mb license status --json
115
115
  ```
116
116
 
117
117
  | Flag | Description |
118
118
  | -------- | ----------------------------------- |
119
119
  | `--json` | Emit JSON. Auto-enabled on non-TTY. |
120
120
 
121
- ### `metabase license remove`
121
+ ### `mb license remove`
122
122
 
123
123
  Clear the stored license.
124
124
 
125
125
  ```sh
126
- metabase license remove --yes
126
+ mb license remove --yes
127
127
  ```
128
128
 
129
129
  | Flag | Description |
@@ -136,24 +136,24 @@ Common output flags (`--json`, `--format`, `--detail`, `--fields`, `--max-bytes`
136
136
 
137
137
  CRUD on `/api/transform`. Bodies for `create` / `update` are JSON; resolution order: `--body` → `--file` → piped stdin (auto-detected when stdin is not a TTY).
138
138
 
139
- ### `metabase transform list`
139
+ ### `mb transform list`
140
140
 
141
141
  ```sh
142
- metabase transform list
143
- metabase transform list --json
142
+ mb transform list
143
+ mb transform list --json
144
144
  ```
145
145
 
146
- ### `metabase transform get <id>`
146
+ ### `mb transform get <id>`
147
147
 
148
148
  ```sh
149
- metabase transform get 1 --json
149
+ mb transform get 1 --json
150
150
  ```
151
151
 
152
- ### `metabase transform create`
152
+ ### `mb transform create`
153
153
 
154
154
  ```sh
155
- cat transform.json | metabase transform create
156
- metabase transform create --file transform.json
155
+ cat transform.json | mb transform create
156
+ mb transform create --file transform.json
157
157
  ```
158
158
 
159
159
  | Flag | Description |
@@ -161,31 +161,31 @@ metabase transform create --file transform.json
161
161
  | `--body <json>` | Inline JSON body. |
162
162
  | `--file <path>` | Path to JSON body file. |
163
163
 
164
- ### `metabase transform update <id>`
164
+ ### `mb transform update <id>`
165
165
 
166
166
  ```sh
167
- metabase transform update 1 --body '{"name":"renamed"}'
167
+ mb transform update 1 --body '{"name":"renamed"}'
168
168
  ```
169
169
 
170
170
  Same `--body` / `--file` resolution as `create`. Stdin is auto-detected when not a TTY.
171
171
 
172
- ### `metabase transform delete <id>`
172
+ ### `mb transform delete <id>`
173
173
 
174
174
  ```sh
175
- metabase transform delete 1 --yes
175
+ mb transform delete 1 --yes
176
176
  ```
177
177
 
178
178
  | Flag | Description |
179
179
  | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
180
180
  | `--yes` | Skip the interactive confirmation prompt. In non-TTY contexts the prompt is skipped automatically (kubectl/gh/docker convention). |
181
181
 
182
- ### `metabase transform run <id>`
182
+ ### `mb transform run <id>`
183
183
 
184
184
  Trigger a manual run. Returns `{message, run_id}` and exits immediately. Pass `--wait` to poll until the run reaches a terminal status (`succeeded`, `failed`, `timeout`, `canceled`); the `final` field on the result holds the polled run state, and the command exits 1 if the final status is anything but `succeeded`.
185
185
 
186
186
  ```sh
187
- metabase transform run 1
188
- metabase transform run 1 --wait --json
187
+ mb transform run 1
188
+ mb transform run 1 --wait --json
189
189
  ```
190
190
 
191
191
  | Flag | Description |
@@ -194,31 +194,31 @@ metabase transform run 1 --wait --json
194
194
  | `--timeout <ms>` | Polling timeout in ms (default 600000). Used with `--wait`. |
195
195
  | `--interval <ms>` | Polling interval in ms (default 2000). Used with `--wait`. |
196
196
 
197
- ### `metabase transform cancel <id>`
197
+ ### `mb transform cancel <id>`
198
198
 
199
199
  Cancel the currently-running run for a transform. Exits 0 with `{canceled: true, id}` on success; exits 1 with a 404 if the transform has no active run.
200
200
 
201
201
  ```sh
202
- metabase transform cancel 1
203
- metabase transform cancel 1 --json
202
+ mb transform cancel 1
203
+ mb transform cancel 1 --json
204
204
  ```
205
205
 
206
- ### `metabase transform get-run <run-id>`
206
+ ### `mb transform get-run <run-id>`
207
207
 
208
208
  Fetch a single run by run id (not transform id). Same compact / `--full` projection convention as `transform get`.
209
209
 
210
210
  ```sh
211
- metabase transform get-run 1 --json
211
+ mb transform get-run 1 --json
212
212
  ```
213
213
 
214
- ### `metabase transform runs`
214
+ ### `mb transform runs`
215
215
 
216
216
  List recent transform runs across all transforms, or filter to one. Drains all pages by default; pass `--limit` to cap.
217
217
 
218
218
  ```sh
219
- metabase transform runs
220
- metabase transform runs --transform-id 1 --json
221
- metabase transform runs --limit 10 --json
219
+ mb transform runs
220
+ mb transform runs --transform-id 1 --json
221
+ mb transform runs --limit 10 --json
222
222
  ```
223
223
 
224
224
  | Flag | Description |
@@ -230,22 +230,22 @@ metabase transform runs --limit 10 --json
230
230
 
231
231
  CRUD on `/api/transform-job`. Bodies for `create` / `update` follow the same `--body` / `--file` / stdin pattern as transforms.
232
232
 
233
- ### `metabase transform-job list`
233
+ ### `mb transform-job list`
234
234
 
235
235
  ```sh
236
- metabase transform-job list --json
236
+ mb transform-job list --json
237
237
  ```
238
238
 
239
- ### `metabase transform-job get <id>`
239
+ ### `mb transform-job get <id>`
240
240
 
241
241
  ```sh
242
- metabase transform-job get 1 --json
242
+ mb transform-job get 1 --json
243
243
  ```
244
244
 
245
- ### `metabase transform-job create`
245
+ ### `mb transform-job create`
246
246
 
247
247
  ```sh
248
- metabase transform-job create --body '{"name":"daily","schedule":"0 0 0 * * ?"}'
248
+ mb transform-job create --body '{"name":"daily","schedule":"0 0 0 * * ?"}'
249
249
  ```
250
250
 
251
251
  | Flag | Description |
@@ -253,16 +253,16 @@ metabase transform-job create --body '{"name":"daily","schedule":"0 0 0 * * ?"}'
253
253
  | `--body <json>` | Inline JSON body. |
254
254
  | `--file <path>` | Path to JSON body file. |
255
255
 
256
- ### `metabase transform-job update <id>`
256
+ ### `mb transform-job update <id>`
257
257
 
258
258
  ```sh
259
- metabase transform-job update 1 --body '{"schedule":"0 0 6 * * ?"}'
259
+ mb transform-job update 1 --body '{"schedule":"0 0 6 * * ?"}'
260
260
  ```
261
261
 
262
- ### `metabase transform-job delete <id>`
262
+ ### `mb transform-job delete <id>`
263
263
 
264
264
  ```sh
265
- metabase transform-job delete 1 --yes
265
+ mb transform-job delete 1 --yes
266
266
  ```
267
267
 
268
268
  | Flag | Description |
@@ -277,13 +277,13 @@ Read warehouse metadata from `/api/database`. The `db` group exposes the full da
277
277
 
278
278
  > **Agent traversal:** prefer the granular path — `db list` → `db schemas <db-id>` → `db schema-tables <db-id> <schema>` → `table get <table-id> --include fields`. On a real warehouse (dozens of schemas, hundreds of tables, dozens of fields per table) the rollup commands (`db metadata`, `db get --include tables.fields`, `db list --include tables`) return megabytes of JSON and exhaust the agent context. Reach for them only on small/dev warehouses where you know the size up front.
279
279
 
280
- ### `metabase db list`
280
+ ### `mb db list`
281
281
 
282
282
  ```sh
283
- metabase db list
284
- metabase db list --json
285
- metabase db list --saved --json
286
- metabase db list --include tables --full --json # rollup: every db with its full table list
283
+ mb db list
284
+ mb db list --json
285
+ mb db list --saved --json
286
+ mb db list --include tables --full --json # rollup: every db with its full table list
287
287
  ```
288
288
 
289
289
  | Flag | Description |
@@ -291,168 +291,168 @@ metabase db list --include tables --full --json # rollup: every db with its fu
291
291
  | `--include <which>` | Hydrate related entities. Currently only `tables` is supported (each database is returned with its `tables`). On real warehouses this returns hundreds of table records per db — use the granular traversal instead. |
292
292
  | `--saved` | Include the Saved Questions virtual database in the list. The virtual db has id `-1337` and no `engine`. |
293
293
 
294
- ### `metabase db get <id>`
294
+ ### `mb db get <id>`
295
295
 
296
296
  ```sh
297
- metabase db get 1
298
- metabase db get 1 --json
299
- metabase db get 1 --include tables --full --json # rollup: db + every table (compact)
300
- metabase db get 1 --include tables.fields --full --json # rollup: db + every table + every field
297
+ mb db get 1
298
+ mb db get 1 --json
299
+ mb db get 1 --include tables --full --json # rollup: db + every table (compact)
300
+ mb db get 1 --include tables.fields --full --json # rollup: db + every table + every field
301
301
  ```
302
302
 
303
303
  | Flag | Description |
304
304
  | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
305
305
  | `--include <which>` | Hydrate related entities. One of `tables` or `tables.fields`. `tables.fields` returns every column of every table in the database in one response — only safe on small/dev warehouses. For a real warehouse use `db schemas` → `db schema-tables` → `table get --include fields`. |
306
306
 
307
- ### `metabase db metadata <id>`
307
+ ### `mb db metadata <id>`
308
308
 
309
309
  Equivalent to `GET /api/database/:id/metadata`: a single database with all its tables and fields rolled up in one response. This is the largest read in the `db` group — on a real warehouse the response will exceed the agent context. Use only when you know the database is small (a seeded dev instance, a sample db, a freshly-bootstrapped test fixture). For agent-driven introspection on a real warehouse, walk `db schemas` → `db schema-tables` → `table get --include fields` instead.
310
310
 
311
311
  ```sh
312
- metabase db metadata 1 --json --full --max-bytes 0
312
+ mb db metadata 1 --json --full --max-bytes 0
313
313
  ```
314
314
 
315
- ### `metabase db schemas <id>`
315
+ ### `mb db schemas <id>`
316
316
 
317
317
  List the schemas in a database. Schemas with no tables are excluded. Cheap and bounded — this is the right entry point for an agent walking a warehouse.
318
318
 
319
319
  ```sh
320
- metabase db schemas 1
321
- metabase db schemas 1 --json
320
+ mb db schemas 1
321
+ mb db schemas 1 --json
322
322
  ```
323
323
 
324
- ### `metabase db schema-tables <id> <schema>`
324
+ ### `mb db schema-tables <id> <schema>`
325
325
 
326
326
  List the tables in one schema, sorted by display name. Returns compact projections without fields — pair with `table get --include fields` (or `table fields <id>`) per table you actually need to introspect.
327
327
 
328
328
  ```sh
329
- metabase db schema-tables 1 public
330
- metabase db schema-tables 1 analytics --json
329
+ mb db schema-tables 1 public
330
+ mb db schema-tables 1 analytics --json
331
331
  ```
332
332
 
333
- ### `metabase db sync-schema <id>`
333
+ ### `mb db sync-schema <id>`
334
334
 
335
335
  Trigger a manual schema sync (`POST /api/database/:id/sync_schema`). Returns `{ id, status: "ok" }` once the sync has been queued; the actual work happens asynchronously on the server.
336
336
 
337
337
  ```sh
338
- metabase db sync-schema 1
339
- metabase db sync-schema 1 --json
338
+ mb db sync-schema 1
339
+ mb db sync-schema 1 --json
340
340
  ```
341
341
 
342
- ### `metabase db rescan-values <id>`
342
+ ### `mb db rescan-values <id>`
343
343
 
344
344
  Trigger a rescan of cached field values (`POST /api/database/:id/rescan_values`). Returns `{ id, status: "ok" }` once the rescan has been queued.
345
345
 
346
346
  ```sh
347
- metabase db rescan-values 1
348
- metabase db rescan-values 1 --json
347
+ mb db rescan-values 1
348
+ mb db rescan-values 1 --json
349
349
  ```
350
350
 
351
351
  ## Tables
352
352
 
353
353
  Inspect and edit warehouse tables via `/api/table`. For agent-driven field introspection, `table get --include fields` is the default — it returns the table plus its columns in a single bounded response.
354
354
 
355
- ### `metabase table list`
355
+ ### `mb table list`
356
356
 
357
357
  Returns every table in the chosen database (or across all databases) as a flat compact list — no fields, no per-table hydration. On a real warehouse with hundreds of tables this is still bounded (kilobytes), but `db schema-tables <db-id> <schema>` is the better starting point when you know the schema.
358
358
 
359
359
  ```sh
360
- metabase table list
361
- metabase table list --db-id 1 --json
360
+ mb table list
361
+ mb table list --db-id 1 --json
362
362
  ```
363
363
 
364
364
  | Flag | Description |
365
365
  | -------------- | ----------------------------------- |
366
366
  | `--db-id <id>` | Filter tables by their database id. |
367
367
 
368
- ### `metabase table get <id>`
368
+ ### `mb table get <id>`
369
369
 
370
- Returns the basic table record (no fields). Pass `--include fields` to route through `/api/table/:id/query_metadata` so the response carries the table's columns compact-projected as `fields` — this is the default agent path for field introspection. Use `metabase table fields <id>` if you only want the fields as a list envelope, or `metabase table metadata <id>` when you also need FKs and dimensions hydrated.
370
+ Returns the basic table record (no fields). Pass `--include fields` to route through `/api/table/:id/query_metadata` so the response carries the table's columns compact-projected as `fields` — this is the default agent path for field introspection. Use `mb table fields <id>` if you only want the fields as a list envelope, or `mb table metadata <id>` when you also need FKs and dimensions hydrated.
371
371
 
372
372
  ```sh
373
- metabase table get 42
374
- metabase table get 42 --json
375
- metabase table get 42 --include fields --json
373
+ mb table get 42
374
+ mb table get 42 --json
375
+ mb table get 42 --include fields --json
376
376
  ```
377
377
 
378
378
  | Flag | Description |
379
379
  | ------------------- | --------------------------------------------------------------------------------------------------- |
380
380
  | `--include <which>` | Hydrate related entities. Currently only `fields` is supported (bundles compact-projected columns). |
381
381
 
382
- ### `metabase table fields <id>`
382
+ ### `mb table fields <id>`
383
383
 
384
384
  List the fields on a table (a thin projection over `query_metadata.fields`). Use this when you want just the field array without the surrounding table metadata.
385
385
 
386
386
  ```sh
387
- metabase table fields 42
388
- metabase table fields 42 --json
387
+ mb table fields 42
388
+ mb table fields 42 --json
389
389
  ```
390
390
 
391
- ### `metabase table metadata <id>`
391
+ ### `mb table metadata <id>`
392
392
 
393
393
  `GET /api/table/:id/query_metadata`: the table with its fields, FKs, dimensions, segments, and measures all hydrated. Heavier than `table get --include fields` — reach for it only when you actually need the FK / dimension / segment / measure data.
394
394
 
395
395
  ```sh
396
- metabase table metadata 42 --json --full --max-bytes 0
396
+ mb table metadata 42 --json --full --max-bytes 0
397
397
  ```
398
398
 
399
- ### `metabase table update <id>`
399
+ ### `mb table update <id>`
400
400
 
401
401
  Patch a table (`PUT /api/table/:id`). Body fields: `display_name`, `description`, `caveats`, `points_of_interest`, `entity_type`, `visibility_type`, `field_order`, `show_in_getting_started`. Pass the body via `--body`, `--file`, or stdin (exactly one).
402
402
 
403
403
  ```sh
404
- metabase table update 42 --body '{"display_name":"Customers"}'
405
- metabase table update 42 --file patch.json
406
- echo '{"description":"Customer dimension"}' | metabase table update 42
404
+ mb table update 42 --body '{"display_name":"Customers"}'
405
+ mb table update 42 --file patch.json
406
+ echo '{"description":"Customer dimension"}' | mb table update 42
407
407
  ```
408
408
 
409
409
  ## Fields
410
410
 
411
411
  Inspect and edit individual columns via `/api/field`.
412
412
 
413
- ### `metabase field get <id>`
413
+ ### `mb field get <id>`
414
414
 
415
415
  ```sh
416
- metabase field get 100
417
- metabase field get 100 --json
416
+ mb field get 100
417
+ mb field get 100 --json
418
418
  ```
419
419
 
420
- ### `metabase field values <id>`
420
+ ### `mb field values <id>`
421
421
 
422
422
  Fetch the cached distinct values list (`GET /api/field/:id/values`). Returns the FieldValues envelope (`{ values, field_id, has_more_values }`); empty `values` on fields whose `has_field_values` is `none` or `search`.
423
423
 
424
424
  ```sh
425
- metabase field values 100 --json
425
+ mb field values 100 --json
426
426
  ```
427
427
 
428
- ### `metabase field summary <id>`
428
+ ### `mb field summary <id>`
429
429
 
430
430
  Row count and distinct count for the field (`GET /api/field/:id/summary`). Metabase returns this as an array-of-pairs; the CLI normalizes it to `{ field_id, count, distincts }`.
431
431
 
432
432
  ```sh
433
- metabase field summary 100
434
- metabase field summary 100 --json
433
+ mb field summary 100
434
+ mb field summary 100 --json
435
435
  ```
436
436
 
437
- ### `metabase field update <id>`
437
+ ### `mb field update <id>`
438
438
 
439
439
  Patch a field (`PUT /api/field/:id`). Body fields: `display_name`, `description`, `caveats`, `points_of_interest`, `semantic_type`, `coercion_strategy`, `fk_target_field_id`, `visibility_type`, `has_field_values`, `settings`, `nfc_path`, `json_unfolding`. Pass the body via `--body`, `--file`, or stdin.
440
440
 
441
441
  ```sh
442
- metabase field update 100 --body '{"description":"customer email","semantic_type":"type/Email"}'
443
- metabase field update 100 --file patch.json
442
+ mb field update 100 --body '{"description":"customer email","semantic_type":"type/Email"}'
443
+ mb field update 100 --file patch.json
444
444
  ```
445
445
 
446
446
  ## Cards
447
447
 
448
448
  CRUD plus query execution on `/api/card`. A "card" is a Metabase question, model, or metric. The `query` subcommand runs the card and either returns Metabase's JSON envelope or streams a raw CSV / XLSX export.
449
449
 
450
- ### `metabase card list`
450
+ ### `mb card list`
451
451
 
452
452
  ```sh
453
- metabase card list
454
- metabase card list --filter archived --json
455
- metabase card list --filter using_model --model-id 42 --json
453
+ mb card list
454
+ mb card list --filter archived --json
455
+ mb card list --filter using_model --model-id 42 --json
456
456
  ```
457
457
 
458
458
  | Flag | Description |
@@ -460,24 +460,24 @@ metabase card list --filter using_model --model-id 42 --json
460
460
  | `--filter <preset>` | One of `all` (default), `mine`, `bookmarked`, `database`, `table`, `archived`, `using_model`, `using_segment`. |
461
461
  | `--model-id <id>` | Required when `--filter` is `database`, `table`, `using_model`, or `using_segment`. |
462
462
 
463
- ### `metabase card get <id>`
463
+ ### `mb card get <id>`
464
464
 
465
465
  ```sh
466
- metabase card get 1
467
- metabase card get 1 --json --detail full
466
+ mb card get 1
467
+ mb card get 1 --json --detail full
468
468
  ```
469
469
 
470
- ### `metabase card query <id>`
470
+ ### `mb card query <id>`
471
471
 
472
472
  Run the card's query. Without `--export-format`, returns the Metabase JSON envelope (`status`, `row_count`, `data: { rows, cols }`, …). With `--export-format csv`, `--export-format json`, or `--export-format xlsx`, the export bytes stream straight to stdout.
473
473
 
474
474
  ```sh
475
- metabase card query 1 --json
476
- metabase card query 1 --json --limit 20
477
- metabase card query 1 --export-format csv > export.csv
478
- metabase card query 1 --export-format json > export.json
479
- metabase card query 1 --export-format xlsx > export.xlsx
480
- metabase card query 1 --parameters '[{"type":"category","value":"A","target":["variable",["template-tag","c"]]}]'
475
+ mb card query 1 --json
476
+ mb card query 1 --json --limit 20
477
+ mb card query 1 --export-format csv > export.csv
478
+ mb card query 1 --export-format json > export.json
479
+ mb card query 1 --export-format xlsx > export.xlsx
480
+ mb card query 1 --parameters '[{"type":"category","value":"A","target":["variable",["template-tag","c"]]}]'
481
481
  ```
482
482
 
483
483
  | Flag | Description |
@@ -488,12 +488,12 @@ metabase card query 1 --parameters '[{"type":"category","value":"A","target":["v
488
488
  | `--format-rows` | Streamed exports only: apply the card's visualization-settings formatting to values (default `false`). |
489
489
  | `--pivot-results` | Streamed exports only: emit the pivoted output for pivot questions (default `false`). |
490
490
 
491
- ### `metabase card create`
491
+ ### `mb card create`
492
492
 
493
493
  ```sh
494
- cat card.json | metabase card create
495
- metabase card create --file card.json
496
- metabase card create --body '{"name":"x","display":"table","dataset_query":{...},"visualization_settings":{}}'
494
+ cat card.json | mb card create
495
+ mb card create --file card.json
496
+ mb card create --body '{"name":"x","display":"table","dataset_query":{...},"visualization_settings":{}}'
497
497
  ```
498
498
 
499
499
  | Flag | Description |
@@ -501,17 +501,17 @@ metabase card create --body '{"name":"x","display":"table","dataset_query":{...}
501
501
  | `--body <json>` | Inline JSON body. |
502
502
  | `--file <path>` | Path to JSON body file. |
503
503
 
504
- ### `metabase card update <id>`
504
+ ### `mb card update <id>`
505
505
 
506
- Patch a card. Body is a partial subset of the create shape (`name`, `display`, `dataset_query`, `visualization_settings`, `description`, `archived`, `collection_id`, `dashboard_id`, `cache_ttl`, `parameters`, `parameter_mappings`, etc.). Only the keys you send are touched. If `dataset_query` is MBQL 5 (`lib/type: "mbql/query"`) it goes through the same pre-flight validation as `card create` and `metabase query`; pass `--skip-validate` to bypass.
506
+ Patch a card. Body is a partial subset of the create shape (`name`, `display`, `dataset_query`, `visualization_settings`, `description`, `archived`, `collection_id`, `dashboard_id`, `cache_ttl`, `parameters`, `parameter_mappings`, etc.). Only the keys you send are touched. If `dataset_query` is MBQL 5 (`lib/type: "mbql/query"`) it goes through the same pre-flight validation as `card create` and `mb query`; pass `--skip-validate` to bypass.
507
507
 
508
508
  ```sh
509
- cat patch.json | metabase card update 1
510
- metabase card update 1 --file patch.json
511
- metabase card update 1 --body '{"name":"renamed"}'
512
- metabase card update 1 --body '{"display":"bar"}'
513
- metabase card update 1 --body '{"archived":true}'
514
- metabase card update 1 --file patch.json --skip-validate
509
+ cat patch.json | mb card update 1
510
+ mb card update 1 --file patch.json
511
+ mb card update 1 --body '{"name":"renamed"}'
512
+ mb card update 1 --body '{"display":"bar"}'
513
+ mb card update 1 --body '{"archived":true}'
514
+ mb card update 1 --file patch.json --skip-validate
515
515
  ```
516
516
 
517
517
  | Flag | Description |
@@ -520,59 +520,59 @@ metabase card update 1 --file patch.json --skip-validate
520
520
  | `--file <path>` | Path to JSON body file. |
521
521
  | `--skip-validate` | Skip the local MBQL 5 pre-flight validation; let the server be the authority. Use only when the bundled schema disagrees with what the server accepts. |
522
522
 
523
- ### `metabase card archive <id>`
523
+ ### `mb card archive <id>`
524
524
 
525
- Soft-delete a card by setting `archived: true`. The archived card stays available via `card list --filter archived` and `card get <id>` until permanently deleted server-side. To unarchive (or otherwise toggle the flag) use `metabase card update <id> --body '{"archived":false}'`.
525
+ Soft-delete a card by setting `archived: true`. The archived card stays available via `card list --filter archived` and `card get <id>` until permanently deleted server-side. To unarchive (or otherwise toggle the flag) use `mb card update <id> --body '{"archived":false}'`.
526
526
 
527
527
  ```sh
528
- metabase card archive 1
529
- metabase card archive 1 --json
528
+ mb card archive 1
529
+ mb card archive 1 --json
530
530
  ```
531
531
 
532
532
  ## Dashboards
533
533
 
534
534
  Read and write dashboards on `/api/dashboard`. A dashboard groups cards (questions, models, metrics) into a single layout. Each card on a dashboard is a "dashcard" — a placement record with its own id, position (`row`/`col`), and size (`size_x`/`size_y`). Dashcards live nested inside the parent dashboard's `dashcards` array; the API has no per-dashcard endpoint, so single-dashcard edits round-trip through `PUT /api/dashboard/:id`.
535
535
 
536
- ### `metabase dashboard list`
536
+ ### `mb dashboard list`
537
537
 
538
538
  ```sh
539
- metabase dashboard list
540
- metabase dashboard list --json
541
- metabase dashboard list --filter archived --json
539
+ mb dashboard list
540
+ mb dashboard list --json
541
+ mb dashboard list --filter archived --json
542
542
  ```
543
543
 
544
544
  | Flag | Description |
545
545
  | ------------------- | ------------------------------------------- |
546
546
  | `--filter <preset>` | One of `all` (default), `mine`, `archived`. |
547
547
 
548
- ### `metabase dashboard get <id>`
548
+ ### `mb dashboard get <id>`
549
549
 
550
550
  ```sh
551
- metabase dashboard get 1
552
- metabase dashboard get 1 --json
553
- metabase dashboard get 1 --json --full
551
+ mb dashboard get 1
552
+ mb dashboard get 1 --json
553
+ mb dashboard get 1 --json --full
554
554
  ```
555
555
 
556
556
  `--full` returns the full hydrated dashboard including the `dashcards` and `tabs` arrays. The default compact view returns only `id`, `name`, `description`, `archived`, and `collection_id`.
557
557
 
558
- ### `metabase dashboard cards <id>`
558
+ ### `mb dashboard cards <id>`
559
559
 
560
560
  List the dashcards on a dashboard.
561
561
 
562
562
  ```sh
563
- metabase dashboard cards 1
564
- metabase dashboard cards 1 --json
563
+ mb dashboard cards 1
564
+ mb dashboard cards 1 --json
565
565
  ```
566
566
 
567
- ### `metabase dashboard create`
567
+ ### `mb dashboard create`
568
568
 
569
569
  The body accepts the same dashboard-level fields as the underlying `POST /api/dashboard` (`name`, `description`, `parameters`, `cache_ttl`, `collection_id`, `collection_position`). It also accepts optional `dashcards` and `tabs`: when either is present, the CLI chains a `PUT /api/dashboard/:id` after the create and returns the updated dashboard with its dashcards/tabs applied. Use a negative `id` on a dashcard to indicate one the server should newly create.
570
570
 
571
571
  ```sh
572
- cat dashboard.json | metabase dashboard create
573
- metabase dashboard create --file dashboard.json
574
- metabase dashboard create --body '{"name":"My Dashboard","collection_id":4}'
575
- metabase dashboard create --body '{"name":"D","dashcards":[{"id":-1,"card_id":42,"row":0,"col":0,"size_x":12,"size_y":6}]}'
572
+ cat dashboard.json | mb dashboard create
573
+ mb dashboard create --file dashboard.json
574
+ mb dashboard create --body '{"name":"My Dashboard","collection_id":4}'
575
+ mb dashboard create --body '{"name":"D","dashcards":[{"id":-1,"card_id":42,"row":0,"col":0,"size_x":12,"size_y":6}]}'
576
576
  ```
577
577
 
578
578
  | Flag | Description |
@@ -580,25 +580,25 @@ metabase dashboard create --body '{"name":"D","dashcards":[{"id":-1,"card_id":42
580
580
  | `--body <json>` | Inline JSON body. |
581
581
  | `--file <path>` | Path to JSON body file. Use `-` to read from stdin. |
582
582
 
583
- ### `metabase dashboard update <id>`
583
+ ### `mb dashboard update <id>`
584
584
 
585
585
  Patch a dashboard. To edit the dashcard set, send the entire `dashcards` array — IDs not in the array get deleted, and a negative `id` indicates a new dashcard the server should create.
586
586
 
587
587
  ```sh
588
- cat patch.json | metabase dashboard update 1
589
- metabase dashboard update 1 --file patch.json
590
- metabase dashboard update 1 --body '{"name":"renamed"}'
591
- metabase dashboard update 1 --body '{"dashcards":[{"id":-1,"card_id":42,"row":0,"col":0,"size_x":12,"size_y":6}]}'
588
+ cat patch.json | mb dashboard update 1
589
+ mb dashboard update 1 --file patch.json
590
+ mb dashboard update 1 --body '{"name":"renamed"}'
591
+ mb dashboard update 1 --body '{"dashcards":[{"id":-1,"card_id":42,"row":0,"col":0,"size_x":12,"size_y":6}]}'
592
592
  ```
593
593
 
594
- ### `metabase dashboard update-dashcard <dashboard-id> <dashcard-id>`
594
+ ### `mb dashboard update-dashcard <dashboard-id> <dashcard-id>`
595
595
 
596
596
  Patch a single dashcard's layout or settings. The command does the round-trip for you: `GET /api/dashboard/:id`, merges the patch into the targeted dashcard while preserving every other dashcard verbatim, then `PUT`s the whole array back.
597
597
 
598
598
  ```sh
599
- metabase dashboard update-dashcard 1 5 --body '{"row":2,"col":0}'
600
- metabase dashboard update-dashcard 1 5 --body '{"size_x":12,"size_y":4}'
601
- cat patch.json | metabase dashboard update-dashcard 1 5
599
+ mb dashboard update-dashcard 1 5 --body '{"row":2,"col":0}'
600
+ mb dashboard update-dashcard 1 5 --body '{"size_x":12,"size_y":4}'
601
+ cat patch.json | mb dashboard update-dashcard 1 5
602
602
  ```
603
603
 
604
604
  | Patch field | Type |
@@ -616,31 +616,31 @@ The patch must contain at least one field; an empty object is rejected before th
616
616
 
617
617
  CRUD on `/api/native-query-snippet`. A snippet is a named, reusable piece of native (SQL) query text — referenced from cards via `{{snippet: Name}}`. The list endpoint returns either active or archived rows (mutually exclusive — pass `--archived` to swap).
618
618
 
619
- ### `metabase snippet list`
619
+ ### `mb snippet list`
620
620
 
621
621
  ```sh
622
- metabase snippet list
623
- metabase snippet list --json
624
- metabase snippet list --archived --json
622
+ mb snippet list
623
+ mb snippet list --json
624
+ mb snippet list --archived --json
625
625
  ```
626
626
 
627
627
  | Flag | Description |
628
628
  | ------------ | ---------------------------------------------- |
629
629
  | `--archived` | Show archived snippets instead of active ones. |
630
630
 
631
- ### `metabase snippet get <id>`
631
+ ### `mb snippet get <id>`
632
632
 
633
633
  ```sh
634
- metabase snippet get 1
635
- metabase snippet get 1 --json --full
634
+ mb snippet get 1
635
+ mb snippet get 1 --json --full
636
636
  ```
637
637
 
638
- ### `metabase snippet create`
638
+ ### `mb snippet create`
639
639
 
640
640
  ```sh
641
- cat snippet.json | metabase snippet create
642
- metabase snippet create --file snippet.json
643
- metabase snippet create --body '{"name":"active","content":"WHERE active = true"}'
641
+ cat snippet.json | mb snippet create
642
+ mb snippet create --file snippet.json
643
+ mb snippet create --body '{"name":"active","content":"WHERE active = true"}'
644
644
  ```
645
645
 
646
646
  | Flag | Description |
@@ -650,15 +650,15 @@ metabase snippet create --body '{"name":"active","content":"WHERE active = true"
650
650
 
651
651
  Body fields: `name` (required), `content` (required), `description` (optional), `collection_id` (optional positive integer).
652
652
 
653
- ### `metabase snippet update <id>`
653
+ ### `mb snippet update <id>`
654
654
 
655
655
  Patch a snippet. Body is a partial subset of the create shape plus `archived`. Only the keys you send are touched.
656
656
 
657
657
  ```sh
658
- cat patch.json | metabase snippet update 1
659
- metabase snippet update 1 --file patch.json
660
- metabase snippet update 1 --body '{"name":"renamed"}'
661
- metabase snippet update 1 --body '{"archived":true}'
658
+ cat patch.json | mb snippet update 1
659
+ mb snippet update 1 --file patch.json
660
+ mb snippet update 1 --body '{"name":"renamed"}'
661
+ mb snippet update 1 --body '{"archived":true}'
662
662
  ```
663
663
 
664
664
  | Flag | Description |
@@ -666,39 +666,39 @@ metabase snippet update 1 --body '{"archived":true}'
666
666
  | `--body <json>` | Inline JSON body. |
667
667
  | `--file <path>` | Path to JSON body file. |
668
668
 
669
- ### `metabase snippet archive <id>`
669
+ ### `mb snippet archive <id>`
670
670
 
671
- Soft-delete a snippet by setting `archived: true`. To unarchive use `metabase snippet update <id> --body '{"archived":false}'`.
671
+ Soft-delete a snippet by setting `archived: true`. To unarchive use `mb snippet update <id> --body '{"archived":false}'`.
672
672
 
673
673
  ```sh
674
- metabase snippet archive 1
675
- metabase snippet archive 1 --json
674
+ mb snippet archive 1
675
+ mb snippet archive 1 --json
676
676
  ```
677
677
 
678
678
  ## Segments
679
679
 
680
680
  CRUD on `/api/segment`. A segment is a saved MBQL filter macro tied to a table — used in card filters to share a reusable predicate. Mutating endpoints require a `revision_message` for the audit log.
681
681
 
682
- ### `metabase segment list`
682
+ ### `mb segment list`
683
683
 
684
684
  ```sh
685
- metabase segment list
686
- metabase segment list --json
685
+ mb segment list
686
+ mb segment list --json
687
687
  ```
688
688
 
689
- ### `metabase segment get <id>`
689
+ ### `mb segment get <id>`
690
690
 
691
691
  ```sh
692
- metabase segment get 1
693
- metabase segment get 1 --json --full
692
+ mb segment get 1
693
+ mb segment get 1 --json --full
694
694
  ```
695
695
 
696
- ### `metabase segment create`
696
+ ### `mb segment create`
697
697
 
698
698
  ```sh
699
- cat segment.json | metabase segment create
700
- metabase segment create --file segment.json
701
- metabase segment create --file segment.json --skip-validate
699
+ cat segment.json | mb segment create
700
+ mb segment create --file segment.json
701
+ mb segment create --file segment.json --skip-validate
702
702
  ```
703
703
 
704
704
  | Flag | Description |
@@ -707,17 +707,17 @@ metabase segment create --file segment.json --skip-validate
707
707
  | `--file <path>` | Path to JSON body file. |
708
708
  | `--skip-validate` | Skip the local MBQL 5 pre-flight validation; let the server be the authority. Use only when the bundled schema disagrees with what the server accepts. |
709
709
 
710
- Body fields: `name` (required), `table_id` (required positive integer), `definition` (required MBQL filter object), `description` (optional). If `definition` is MBQL 5 (`lib/type: "mbql/query"`) it goes through the same pre-flight validation as `card create` and `metabase query`; pass `--skip-validate` to bypass.
710
+ Body fields: `name` (required), `table_id` (required positive integer), `definition` (required MBQL filter object), `description` (optional). If `definition` is MBQL 5 (`lib/type: "mbql/query"`) it goes through the same pre-flight validation as `card create` and `mb query`; pass `--skip-validate` to bypass.
711
711
 
712
- ### `metabase segment update <id>`
712
+ ### `mb segment update <id>`
713
713
 
714
714
  Patch a segment. The body MUST include `revision_message`. Other keys are partial: `name`, `definition`, `archived`, `description`, `caveats`, `points_of_interest`, `show_in_getting_started`. If `definition` is MBQL 5 (`lib/type: "mbql/query"`) it goes through the same pre-flight validation as `segment create`; pass `--skip-validate` to bypass.
715
715
 
716
716
  ```sh
717
- cat patch.json | metabase segment update 1
718
- metabase segment update 1 --file patch.json
719
- metabase segment update 1 --body '{"name":"renamed","revision_message":"rename"}'
720
- metabase segment update 1 --file patch.json --skip-validate
717
+ cat patch.json | mb segment update 1
718
+ mb segment update 1 --file patch.json
719
+ mb segment update 1 --body '{"name":"renamed","revision_message":"rename"}'
720
+ mb segment update 1 --file patch.json --skip-validate
721
721
  ```
722
722
 
723
723
  | Flag | Description |
@@ -726,13 +726,13 @@ metabase segment update 1 --file patch.json --skip-validate
726
726
  | `--file <path>` | Path to JSON body file. |
727
727
  | `--skip-validate` | Skip the local MBQL 5 pre-flight validation; let the server be the authority. Use only when the bundled schema disagrees with what the server accepts. |
728
728
 
729
- ### `metabase segment archive <id>`
729
+ ### `mb segment archive <id>`
730
730
 
731
- Soft-delete a segment by setting `archived: true`. The default revision message is `"Archived via metabase CLI"`; override with `--revision-message`.
731
+ Soft-delete a segment by setting `archived: true`. The default revision message is `"Archived via mb CLI"`; override with `--revision-message`.
732
732
 
733
733
  ```sh
734
- metabase segment archive 1
735
- metabase segment archive 1 --revision-message "deprecated"
734
+ mb segment archive 1
735
+ mb segment archive 1 --revision-message "deprecated"
736
736
  ```
737
737
 
738
738
  | Flag | Description |
@@ -743,26 +743,26 @@ metabase segment archive 1 --revision-message "deprecated"
743
743
 
744
744
  CRUD on `/api/measure`. A measure is a saved MBQL aggregation (a single `:aggregation` clause) tied to a table — referenced from cards and metrics to share a reusable computation. Mutating endpoints require a `revision_message` for the audit log.
745
745
 
746
- ### `metabase measure list`
746
+ ### `mb measure list`
747
747
 
748
748
  ```sh
749
- metabase measure list
750
- metabase measure list --json
749
+ mb measure list
750
+ mb measure list --json
751
751
  ```
752
752
 
753
- ### `metabase measure get <id>`
753
+ ### `mb measure get <id>`
754
754
 
755
755
  ```sh
756
- metabase measure get 1
757
- metabase measure get 1 --json --full
756
+ mb measure get 1
757
+ mb measure get 1 --json --full
758
758
  ```
759
759
 
760
- ### `metabase measure create`
760
+ ### `mb measure create`
761
761
 
762
762
  ```sh
763
- cat measure.json | metabase measure create
764
- metabase measure create --file measure.json
765
- metabase measure create --file measure.json --skip-validate
763
+ cat measure.json | mb measure create
764
+ mb measure create --file measure.json
765
+ mb measure create --file measure.json --skip-validate
766
766
  ```
767
767
 
768
768
  | Flag | Description |
@@ -771,17 +771,17 @@ metabase measure create --file measure.json --skip-validate
771
771
  | `--file <path>` | Path to JSON body file. |
772
772
  | `--skip-validate` | Skip the local MBQL 5 pre-flight validation; let the server be the authority. Use only when the bundled schema disagrees with what the server accepts. |
773
773
 
774
- Body fields: `name` (required), `table_id` (required positive integer), `definition` (required MBQL aggregation object), `description` (optional). If `definition` is MBQL 5 (`lib/type: "mbql/query"`) it goes through the same pre-flight validation as `card create` and `metabase query`; pass `--skip-validate` to bypass.
774
+ Body fields: `name` (required), `table_id` (required positive integer), `definition` (required MBQL aggregation object), `description` (optional). If `definition` is MBQL 5 (`lib/type: "mbql/query"`) it goes through the same pre-flight validation as `card create` and `mb query`; pass `--skip-validate` to bypass.
775
775
 
776
- ### `metabase measure update <id>`
776
+ ### `mb measure update <id>`
777
777
 
778
778
  Patch a measure. The body MUST include `revision_message`. Other keys are partial: `name`, `definition`, `archived`, `description`. If `definition` is MBQL 5 (`lib/type: "mbql/query"`) it goes through the same pre-flight validation as `measure create`; pass `--skip-validate` to bypass.
779
779
 
780
780
  ```sh
781
- cat patch.json | metabase measure update 1
782
- metabase measure update 1 --file patch.json
783
- metabase measure update 1 --body '{"name":"renamed","revision_message":"rename"}'
784
- metabase measure update 1 --file patch.json --skip-validate
781
+ cat patch.json | mb measure update 1
782
+ mb measure update 1 --file patch.json
783
+ mb measure update 1 --body '{"name":"renamed","revision_message":"rename"}'
784
+ mb measure update 1 --file patch.json --skip-validate
785
785
  ```
786
786
 
787
787
  | Flag | Description |
@@ -790,13 +790,13 @@ metabase measure update 1 --file patch.json --skip-validate
790
790
  | `--file <path>` | Path to JSON body file. |
791
791
  | `--skip-validate` | Skip the local MBQL 5 pre-flight validation; let the server be the authority. Use only when the bundled schema disagrees with what the server accepts. |
792
792
 
793
- ### `metabase measure archive <id>`
793
+ ### `mb measure archive <id>`
794
794
 
795
- Soft-delete a measure by setting `archived: true`. The default revision message is `"Archived via metabase CLI"`; override with `--revision-message`.
795
+ Soft-delete a measure by setting `archived: true`. The default revision message is `"Archived via mb CLI"`; override with `--revision-message`.
796
796
 
797
797
  ```sh
798
- metabase measure archive 1
799
- metabase measure archive 1 --revision-message "deprecated"
798
+ mb measure archive 1
799
+ mb measure archive 1 --revision-message "deprecated"
800
800
  ```
801
801
 
802
802
  | Flag | Description |
@@ -807,41 +807,41 @@ metabase measure archive 1 --revision-message "deprecated"
807
807
 
808
808
  Read collections on `/api/collection`. Collections are the folders that contain cards, dashboards, and other collections. The list endpoint surfaces a virtual root collection (id `"root"`) alongside regular numeric ids; the get endpoint accepts only the numeric id.
809
809
 
810
- ### `metabase collection list`
810
+ ### `mb collection list`
811
811
 
812
812
  ```sh
813
- metabase collection list
814
- metabase collection list --json
815
- metabase collection list --filter archived --json
813
+ mb collection list
814
+ mb collection list --json
815
+ mb collection list --filter archived --json
816
816
  ```
817
817
 
818
818
  | Flag | Description |
819
819
  | ------------------- | --------------------------------------------------------------------------------------------------------------- |
820
820
  | `--filter <preset>` | One of `all` (default), `archived` (returns the trash collection only), `personal` (only personal collections). |
821
821
 
822
- ### `metabase collection get <id>`
822
+ ### `mb collection get <id>`
823
823
 
824
824
  `<id>` accepts any of: a positive integer collection id, the literal `root` (the virtual "Our analytics" root), the literal `trash` (the trash collection), or a 21-character entity id (NanoID). Anything else is rejected with a `ConfigError` before any HTTP call.
825
825
 
826
826
  ```sh
827
- metabase collection get 4
828
- metabase collection get root --json
829
- metabase collection get trash --json
830
- metabase collection get voo1If9y8Sld0lXej6xl0 --json
831
- metabase collection get 4 --json --full
827
+ mb collection get 4
828
+ mb collection get root --json
829
+ mb collection get trash --json
830
+ mb collection get voo1If9y8Sld0lXej6xl0 --json
831
+ mb collection get 4 --json --full
832
832
  ```
833
833
 
834
834
  `--full` returns the full hydrated collection including `slug`, `entity_id`, `can_write`, `namespace`, and `personal_owner_id`. The default compact view returns `id`, `name`, `description`, `archived`, `location`, `parent_id`, `type`, `authority_level`, and `is_personal`. The root collection has a stripped-down shape — `archived`, `description`, `location`, `type`, etc. are absent rather than `null`.
835
835
 
836
- ### `metabase collection items <id>`
836
+ ### `mb collection items <id>`
837
837
 
838
838
  List the cards, dashboards, sub-collections, and other content stored inside a collection. The CLI drains all pages of `/api/collection/:id/items`; pass `--limit` to cap the result. `<id>` accepts the same forms as `collection get` — including `root` for top-level content (items there have `collection_id: null`).
839
839
 
840
840
  ```sh
841
- metabase collection items 4
842
- metabase collection items root --json
843
- metabase collection items 4 --models card,dashboard --json
844
- metabase collection items 4 --pinned-state is_pinned --json
841
+ mb collection items 4
842
+ mb collection items root --json
843
+ mb collection items 4 --models card,dashboard --json
844
+ mb collection items 4 --pinned-state is_pinned --json
845
845
  ```
846
846
 
847
847
  | Flag | Description |
@@ -851,23 +851,23 @@ metabase collection items 4 --pinned-state is_pinned --json
851
851
  | `--pinned-state <state>` | One of `all`, `is_pinned`, `is_not_pinned`. |
852
852
  | `--limit <n>` | Cap total items returned. Default: drain all pages. |
853
853
 
854
- ### `metabase collection tree`
854
+ ### `mb collection tree`
855
855
 
856
856
  Fetch the full collection hierarchy as a nested tree. Output is always JSON — the recursive structure does not render meaningfully as a key/value table.
857
857
 
858
858
  ```sh
859
- metabase collection tree
860
- metabase collection tree --json
859
+ mb collection tree
860
+ mb collection tree --json
861
861
  ```
862
862
 
863
- ### `metabase collection create`
863
+ ### `mb collection create`
864
864
 
865
865
  Create a collection from a JSON spec. The body accepts the same fields as `POST /api/collection`: `name` (required), `description`, `parent_id` (omit or `null` for the root), `namespace`, and `authority_level`.
866
866
 
867
867
  ```sh
868
- cat collection.json | metabase collection create
869
- metabase collection create --file collection.json
870
- metabase collection create --body '{"name":"My Collection","parent_id":4}'
868
+ cat collection.json | mb collection create
869
+ mb collection create --file collection.json
870
+ mb collection create --body '{"name":"My Collection","parent_id":4}'
871
871
  ```
872
872
 
873
873
  | Flag | Description |
@@ -879,34 +879,34 @@ metabase collection create --body '{"name":"My Collection","parent_id":4}'
879
879
 
880
880
  Read and write Metabase instance settings via `/api/setting`. Listing all settings requires admin privileges; per-key reads/writes additionally enforce per-setting access. Setting values are always JSON — `"main"` is the string `main`, `42` is a number, `null` deletes the override and resets the value to its default.
881
881
 
882
- ### `metabase setting list`
882
+ ### `mb setting list`
883
883
 
884
884
  ```sh
885
- metabase setting list
886
- metabase setting list --json --max-bytes 0
885
+ mb setting list
886
+ mb setting list --json --max-bytes 0
887
887
  ```
888
888
 
889
889
  Returns a `ListEnvelope` of compact entries (`key`, `value`, `is_env_setting`, `env_name`). Pass `--full` for the full per-row payload (also includes `description` and `default`). The full payload can exceed the default `--max-bytes` cap; pass `--max-bytes 0` to disable the cap.
890
890
 
891
- ### `metabase setting get <key>`
891
+ ### `mb setting get <key>`
892
892
 
893
893
  ```sh
894
- metabase setting get site-name
895
- metabase setting get remote-sync-branch --json
894
+ mb setting get site-name
895
+ mb setting get remote-sync-branch --json
896
896
  ```
897
897
 
898
898
  Returns `{ key, value }` for a single setting. Settings whose stored value matches the default — or that come from an env var — surface as `value: null`.
899
899
 
900
- ### `metabase setting set <key> [value]`
900
+ ### `mb setting set <key> [value]`
901
901
 
902
902
  Set or delete a setting. The value is parsed strictly as JSON: pass `'"main"'` for the string `main`, `true`/`42` for booleans/numbers, `null` to delete the stored override (resets to default).
903
903
 
904
904
  ```sh
905
- metabase setting set remote-sync-branch '"main"'
906
- metabase setting set anon-tracking-enabled true
907
- echo '"main"' | metabase setting set remote-sync-branch
908
- metabase setting set remote-sync-branch --file value.json
909
- metabase setting set remote-sync-branch null
905
+ mb setting set remote-sync-branch '"main"'
906
+ mb setting set anon-tracking-enabled true
907
+ echo '"main"' | mb setting set remote-sync-branch
908
+ mb setting set remote-sync-branch --file value.json
909
+ mb setting set remote-sync-branch null
910
910
  ```
911
911
 
912
912
  | Flag | Description |
@@ -917,14 +917,14 @@ Sources are resolved in this order: positional, `--file`, piped stdin. Provide e
917
917
 
918
918
  ## Search
919
919
 
920
- ### `metabase search [query]`
920
+ ### `mb search [query]`
921
921
 
922
922
  Search Metabase content (cards, dashboards, collections, tables, …). Returns a `ListEnvelope` of compact search results by default; pass `--detail full` for the full per-row payload.
923
923
 
924
924
  ```sh
925
- metabase search orders
926
- metabase search --models card,dashboard --limit 10 --json
927
- metabase search products --archived
925
+ mb search orders
926
+ mb search --models card,dashboard --limit 10 --json
927
+ mb search products --archived
928
928
  ```
929
929
 
930
930
  | Flag | Description |
@@ -939,69 +939,69 @@ metabase search products --archived
939
939
 
940
940
  Drive Metabase Enterprise Remote Sync (`/api/ee/remote-sync`) — import / export Metabase content against a configured git remote, inspect dirty state, and manage branches. All git-sync commands require an active EE token and superuser credentials.
941
941
 
942
- ### `metabase git-sync status`
942
+ ### `mb git-sync status`
943
943
 
944
944
  Roll up the current sync state in one call: configured branch, dirty flag, and the most recent sync task (or `null` if none has ever run).
945
945
 
946
946
  ```sh
947
- metabase git-sync status
948
- metabase git-sync status --json
947
+ mb git-sync status
948
+ mb git-sync status --json
949
949
  ```
950
950
 
951
- ### `metabase git-sync is-dirty`
951
+ ### `mb git-sync is-dirty`
952
952
 
953
953
  Boolean check for whether any synced collection has unsynced local changes.
954
954
 
955
955
  ```sh
956
- metabase git-sync is-dirty --json
956
+ mb git-sync is-dirty --json
957
957
  ```
958
958
 
959
- ### `metabase git-sync has-remote-changes`
959
+ ### `mb git-sync has-remote-changes`
960
960
 
961
961
  Compare the latest version on the remote branch against the version Metabase last imported. Cached for a short TTL server-side; pass `--force-refresh` to bypass.
962
962
 
963
963
  ```sh
964
- metabase git-sync has-remote-changes
965
- metabase git-sync has-remote-changes --force-refresh --json
964
+ mb git-sync has-remote-changes
965
+ mb git-sync has-remote-changes --force-refresh --json
966
966
  ```
967
967
 
968
968
  | Flag | Description |
969
969
  | ----------------- | --------------------------------------------------- |
970
970
  | `--force-refresh` | Bypass the in-memory cache and re-check the remote. |
971
971
 
972
- ### `metabase git-sync dirty`
972
+ ### `mb git-sync dirty`
973
973
 
974
974
  List every object that has unsynced local changes (compact list envelope; `--full` for the per-row payload).
975
975
 
976
976
  ```sh
977
- metabase git-sync dirty
978
- metabase git-sync dirty --json
977
+ mb git-sync dirty
978
+ mb git-sync dirty --json
979
979
  ```
980
980
 
981
- ### `metabase git-sync current-task`
981
+ ### `mb git-sync current-task`
982
982
 
983
983
  Fetch the most recent sync task. Renders `{ status: "idle" }` when no task has ever run, otherwise the full task with its hydrated `status`.
984
984
 
985
985
  ```sh
986
- metabase git-sync current-task
987
- metabase git-sync current-task --json
986
+ mb git-sync current-task
987
+ mb git-sync current-task --json
988
988
  ```
989
989
 
990
- ### `metabase git-sync cancel-task`
990
+ ### `mb git-sync cancel-task`
991
991
 
992
992
  Cancel the currently running sync task. Fails with HTTP 400 if no task is running.
993
993
 
994
994
  ```sh
995
- metabase git-sync cancel-task --json
995
+ mb git-sync cancel-task --json
996
996
  ```
997
997
 
998
- ### `metabase git-sync wait`
998
+ ### `mb git-sync wait`
999
999
 
1000
1000
  Poll `/current-task` until it reaches a terminal status (`successful`, `errored`, `cancelled`, `timed-out`, `conflict`). Exits 0 on `successful` or `cancelled`; exits 1 on `errored` / `timed-out` / `conflict`. Returns immediately with `{ status: "idle" }` if no task is running.
1001
1001
 
1002
1002
  ```sh
1003
- metabase git-sync wait
1004
- metabase git-sync wait --timeout 300000 --json
1003
+ mb git-sync wait
1004
+ mb git-sync wait --timeout 300000 --json
1005
1005
  ```
1006
1006
 
1007
1007
  | Flag | Description |
@@ -1009,14 +1009,14 @@ metabase git-sync wait --timeout 300000 --json
1009
1009
  | `--timeout <ms>` | Polling timeout in ms (default 600000). |
1010
1010
  | `--interval <ms>` | Polling interval in ms (default 2000). |
1011
1011
 
1012
- ### `metabase git-sync import`
1012
+ ### `mb git-sync import`
1013
1013
 
1014
1014
  Import content from the configured git remote into Metabase (repo → Metabase). Auto-polls until the resulting task reaches a terminal status; pass `--no-wait` to return immediately after kickoff.
1015
1015
 
1016
1016
  ```sh
1017
- metabase git-sync import
1018
- metabase git-sync import --branch main --json
1019
- metabase git-sync import --force --no-wait
1017
+ mb git-sync import
1018
+ mb git-sync import --branch main --json
1019
+ mb git-sync import --force --no-wait
1020
1020
  ```
1021
1021
 
1022
1022
  | Flag | Description |
@@ -1027,14 +1027,14 @@ metabase git-sync import --force --no-wait
1027
1027
  | `--timeout <ms>` | Polling timeout in ms (default 600000). Used with `--wait`. |
1028
1028
  | `--interval <ms>` | Polling interval in ms (default 2000). Used with `--wait`. |
1029
1029
 
1030
- ### `metabase git-sync export`
1030
+ ### `mb git-sync export`
1031
1031
 
1032
1032
  Export Metabase changes back to the configured git remote (Metabase → repo). Auto-polls by default.
1033
1033
 
1034
1034
  ```sh
1035
- metabase git-sync export -m "update dashboards"
1036
- metabase git-sync export --branch main --json
1037
- metabase git-sync export --no-wait
1035
+ mb git-sync export -m "update dashboards"
1036
+ mb git-sync export --branch main --json
1037
+ mb git-sync export --no-wait
1038
1038
  ```
1039
1039
 
1040
1040
  | Flag | Description |
@@ -1046,77 +1046,77 @@ metabase git-sync export --no-wait
1046
1046
  | `--timeout <ms>` | Polling timeout in ms (default 600000). Used with `--wait`. |
1047
1047
  | `--interval <ms>` | Polling interval in ms (default 2000). Used with `--wait`. |
1048
1048
 
1049
- ### `metabase git-sync stash`
1049
+ ### `mb git-sync stash`
1050
1050
 
1051
1051
  Export the current Metabase state to a NEW branch on the remote and switch sync to it. Requires `remote-sync-type` to be `read-write`.
1052
1052
 
1053
1053
  ```sh
1054
- metabase git-sync stash --new-branch wip
1055
- metabase git-sync stash --new-branch wip -m "work in progress" --json
1054
+ mb git-sync stash --new-branch wip
1055
+ mb git-sync stash --new-branch wip -m "work in progress" --json
1056
1056
  ```
1057
1057
 
1058
1058
  | Flag | Description |
1059
1059
  | ----------------------- | -------------------------------------------------------------- |
1060
1060
  | `--new-branch <name>` | Required. Branch to create and export to. |
1061
- | `--message <msg>`, `-m` | Commit message (default `Stashed from metabase CLI`). |
1061
+ | `--message <msg>`, `-m` | Commit message (default `Stashed from mb CLI`). |
1062
1062
  | `--wait` / `--no-wait` | Poll until the task reaches a terminal status (default: wait). |
1063
1063
  | `--timeout <ms>` | Polling timeout in ms. Used with `--wait`. |
1064
1064
  | `--interval <ms>` | Polling interval in ms. Used with `--wait`. |
1065
1065
 
1066
- ### `metabase git-sync branches`
1066
+ ### `mb git-sync branches`
1067
1067
 
1068
1068
  List branches available on the configured git remote.
1069
1069
 
1070
1070
  ```sh
1071
- metabase git-sync branches --json
1071
+ mb git-sync branches --json
1072
1072
  ```
1073
1073
 
1074
- ### `metabase git-sync create-branch <name>`
1074
+ ### `mb git-sync create-branch <name>`
1075
1075
 
1076
1076
  Create a new branch on the git remote (from the last imported version) and switch sync to it.
1077
1077
 
1078
1078
  ```sh
1079
- metabase git-sync create-branch feat/dashboards
1080
- metabase git-sync create-branch feat/x --json
1079
+ mb git-sync create-branch feat/dashboards
1080
+ mb git-sync create-branch feat/x --json
1081
1081
  ```
1082
1082
 
1083
- ### `metabase git-sync add-collection <id>`
1083
+ ### `mb git-sync add-collection <id>`
1084
1084
 
1085
1085
  Mark a collection as git-synced. The toggle cascades to every descendant by `location` prefix, so flagging a parent flags the whole subtree. Returns `{ success, task_id? }`; `task_id` only appears when the toggle triggers a follow-up task (e.g. a finalization import after switching to read-only mode).
1086
1086
 
1087
1087
  ```sh
1088
- metabase git-sync add-collection 12
1089
- metabase git-sync add-collection 12 --json --profile prod
1088
+ mb git-sync add-collection 12
1089
+ mb git-sync add-collection 12 --json --profile prod
1090
1090
  ```
1091
1091
 
1092
- The server rejects toggles while `remote-sync-type` is `read-only` (the install default). Switch first with `metabase setting set remote-sync-type '"read-write"'`.
1092
+ The server rejects toggles while `remote-sync-type` is `read-only` (the install default). Switch first with `mb setting set remote-sync-type '"read-write"'`.
1093
1093
 
1094
- ### `metabase git-sync remove-collection <id>`
1094
+ ### `mb git-sync remove-collection <id>`
1095
1095
 
1096
1096
  Unmark a collection as git-synced. Same cascade and same `read-only` precondition as `add-collection`.
1097
1097
 
1098
1098
  ```sh
1099
- metabase git-sync remove-collection 12
1100
- metabase git-sync remove-collection 12 --json --profile prod
1099
+ mb git-sync remove-collection 12
1100
+ mb git-sync remove-collection 12 --json --profile prod
1101
1101
  ```
1102
1102
 
1103
1103
  ## Workspaces
1104
1104
 
1105
1105
  CRUD on `/api/ee/workspace-manager`. Run against the workspace-manager parent instance.
1106
1106
 
1107
- ### `metabase workspace list`
1107
+ ### `mb workspace list`
1108
1108
 
1109
1109
  ```sh
1110
- metabase workspace list
1111
- metabase workspace list --json
1110
+ mb workspace list
1111
+ mb workspace list --json
1112
1112
  ```
1113
1113
 
1114
- ### `metabase workspace create`
1114
+ ### `mb workspace create`
1115
1115
 
1116
1116
  ```sh
1117
- metabase workspace create --name analytics
1118
- echo '{"name":"analytics"}' | metabase workspace create
1119
- metabase workspace create --file workspace.json
1117
+ mb workspace create --name analytics
1118
+ echo '{"name":"analytics"}' | mb workspace create
1119
+ mb workspace create --file workspace.json
1120
1120
  ```
1121
1121
 
1122
1122
  | Flag | Description |
@@ -1125,14 +1125,14 @@ metabase workspace create --file workspace.json
1125
1125
  | `--body <json>` | Inline JSON body. |
1126
1126
  | `--file <path>` | Path to JSON body file. |
1127
1127
 
1128
- ### `metabase workspace database provision <workspace-id>`
1128
+ ### `mb workspace database provision <workspace-id>`
1129
1129
 
1130
1130
  Provision a database into a workspace. The backend kicks off the work asynchronously and returns the workspace with the new entry in `status: "provisioning"`. Pass `--wait` to poll until the entry reaches `status: "provisioned"` and surface the polled state instead of the initial response.
1131
1131
 
1132
1132
  ```sh
1133
- metabase workspace database provision 1 --database-id 5 --schemas analytics,github
1134
- metabase workspace database provision 1 --database-id 5 --schemas analytics --wait
1135
- metabase workspace database provision 1 --file provision.json
1133
+ mb workspace database provision 1 --database-id 5 --schemas analytics,github
1134
+ mb workspace database provision 1 --database-id 5 --schemas analytics --wait
1135
+ mb workspace database provision 1 --file provision.json
1136
1136
  ```
1137
1137
 
1138
1138
  | Flag | Description |
@@ -1145,14 +1145,14 @@ metabase workspace database provision 1 --file provision.json
1145
1145
  | `--timeout <ms>` | Polling timeout in ms (default 600000). Used with `--wait`. |
1146
1146
  | `--interval <ms>` | Polling interval in ms (default 2000). Used with `--wait`. |
1147
1147
 
1148
- ### `metabase workspace database update <workspace-id> <db-id>`
1148
+ ### `mb workspace database update <workspace-id> <db-id>`
1149
1149
 
1150
1150
  Update a workspace's provisioned database (server-side this is deprovision + provision). Body accepts only `input` — the database id comes from the URL.
1151
1151
 
1152
1152
  ```sh
1153
- metabase workspace database update 1 5 --schemas analytics,github
1154
- metabase workspace database update 1 5 --schemas analytics --wait
1155
- metabase workspace database update 1 5 --file update.json
1153
+ mb workspace database update 1 5 --schemas analytics,github
1154
+ mb workspace database update 1 5 --schemas analytics --wait
1155
+ mb workspace database update 1 5 --file update.json
1156
1156
  ```
1157
1157
 
1158
1158
  | Flag | Description |
@@ -1164,11 +1164,11 @@ metabase workspace database update 1 5 --file update.json
1164
1164
  | `--timeout <ms>` | Polling timeout in ms (default 600000). Used with `--wait`. |
1165
1165
  | `--interval <ms>` | Polling interval in ms (default 2000). Used with `--wait`. |
1166
1166
 
1167
- ### `metabase workspace database deprovision <workspace-id> <db-id>`
1167
+ ### `mb workspace database deprovision <workspace-id> <db-id>`
1168
1168
 
1169
1169
  ```sh
1170
- metabase workspace database deprovision 1 5 --yes
1171
- metabase workspace database deprovision 1 5 --yes --wait
1170
+ mb workspace database deprovision 1 5 --yes
1171
+ mb workspace database deprovision 1 5 --yes --wait
1172
1172
  ```
1173
1173
 
1174
1174
  | Flag | Description |
@@ -1182,21 +1182,21 @@ metabase workspace database deprovision 1 5 --yes --wait
1182
1182
 
1183
1183
  These commands manage a Docker container that serves as the workspace's child Metabase instance. State lives in Docker labels and a named volume — there is no per-workspace local state directory. The container is named `metabase-workspace-<id>`; the app-db volume is `metabase-workspace-<id>-appdb`.
1184
1184
 
1185
- ### `metabase workspace start <id>`
1185
+ ### `mb workspace start <id>`
1186
1186
 
1187
1187
  ```sh
1188
- metabase workspace start 1
1189
- metabase workspace start 1 --wait
1190
- metabase workspace start 1 --port 3100
1191
- metabase workspace start 1 --image metabase/metabase-dev:feature-workspaces-v2 --no-pull
1192
- metabase workspace start 1 --force
1193
- metabase workspace start 1 --repo /path/to/sync-repo --wait
1194
- metabase workspace start 1 --repo /path/to/sync-repo --repo-branch dev --repo-mode read-only
1188
+ mb workspace start 1
1189
+ mb workspace start 1 --wait
1190
+ mb workspace start 1 --port 3100
1191
+ mb workspace start 1 --image metabase/metabase-dev:feature-workspaces-v2 --no-pull
1192
+ mb workspace start 1 --force
1193
+ mb workspace start 1 --repo /path/to/sync-repo --wait
1194
+ mb workspace start 1 --repo /path/to/sync-repo --repo-branch dev --repo-mode read-only
1195
1195
  ```
1196
1196
 
1197
- Resolves the parent via the active profile (or `--profile`/`--url`/`--api-key`) and the EE license via `resolveLicenseToken` (the same path `metabase license set` writes to). Refuses to start if the workspace has any database that isn't `status: "provisioned"`.
1197
+ Resolves the parent via the active profile (or `--profile`/`--url`/`--api-key`) and the EE license via `resolveLicenseToken` (the same path `mb license set` writes to). Refuses to start if the workspace has any database that isn't `status: "provisioned"`.
1198
1198
 
1199
- The boot bundle (`config.yml`, `credentials.json`, optional `metadata.json`) is built in process memory and tar-streamed into the container's `/mw-config/` directory through `docker cp -`; no host-disk artifact is created. The CLI generates a per-workspace admin user + API key, injects them into the YAML before shipping, and stores the same values in `credentials.json` for later retrieval via `metabase workspace credentials`. Once the child logs that it has read `config.yml`, the CLI scrubs the in-container copy (`docker exec rm /mw-config/config.yml`) so the warehouse credentials in `details.password` no longer linger; `credentials.json` stays.
1199
+ The boot bundle (`config.yml`, `credentials.json`, optional `metadata.json`) is built in process memory and tar-streamed into the container's `/mw-config/` directory through `docker cp -`; no host-disk artifact is created. The CLI generates a per-workspace admin user + API key, injects them into the YAML before shipping, and stores the same values in `credentials.json` for later retrieval via `mb workspace credentials`. Once the child logs that it has read `config.yml`, the CLI scrubs the in-container copy (`docker exec rm /mw-config/config.yml`) so the warehouse credentials in `details.password` no longer linger; `credentials.json` stays.
1200
1200
 
1201
1201
  By default `start` returns once the bundle has been consumed by the child (`state: "starting"`); pass `--wait` to also block until `/api/health` reports ready and the response reports `state: "running"`.
1202
1202
 
@@ -1215,20 +1215,20 @@ When `--repo <host-path>` is passed, the CLI bind-mounts the host directory at `
1215
1215
  | `--repo-branch <name>` | `remote-sync-branch` value (default: current branch of the host repo). |
1216
1216
  | `--repo-mode <mode>` | `remote-sync-type`: `read-write` (default) or `read-only`. Read-only also makes the bind mount read-only. |
1217
1217
 
1218
- ### `metabase workspace stop <id>`
1218
+ ### `mb workspace stop <id>`
1219
1219
 
1220
1220
  ```sh
1221
- metabase workspace stop 1
1222
- metabase workspace stop 1 --json
1221
+ mb workspace stop 1
1222
+ mb workspace stop 1 --json
1223
1223
  ```
1224
1224
 
1225
1225
  Stops the running container; no-ops if it's already exited or missing. Reports the prior state.
1226
1226
 
1227
- ### `metabase workspace remove <id>`
1227
+ ### `mb workspace remove <id>`
1228
1228
 
1229
1229
  ```sh
1230
- metabase workspace remove 1 --yes
1231
- metabase workspace remove 1 --keep-volume --yes
1230
+ mb workspace remove 1 --yes
1231
+ mb workspace remove 1 --keep-volume --yes
1232
1232
  ```
1233
1233
 
1234
1234
  Stops and removes the container. By default, also removes the app-db volume — pass `--keep-volume` to preserve it across rebuilds. **Does not affect the remote workspace** on the parent.
@@ -1238,12 +1238,12 @@ Stops and removes the container. By default, also removes the app-db volume —
1238
1238
  | `--yes` | Skip the interactive confirmation prompt. In non-TTY contexts the prompt is skipped automatically (kubectl/gh/docker convention). |
1239
1239
  | `--keep-volume` | Preserve the app-db volume (`metabase-workspace-<id>-appdb`). |
1240
1240
 
1241
- ### `metabase workspace logs <id>`
1241
+ ### `mb workspace logs <id>`
1242
1242
 
1243
1243
  ```sh
1244
- metabase workspace logs 1
1245
- metabase workspace logs 1 --follow
1246
- metabase workspace logs 1 --tail 500
1244
+ mb workspace logs 1
1245
+ mb workspace logs 1 --follow
1246
+ mb workspace logs 1 --tail 500
1247
1247
  ```
1248
1248
 
1249
1249
  Passthrough to `docker logs`. Output streams directly to your terminal; Ctrl-C terminates a follow.
@@ -1253,29 +1253,29 @@ Passthrough to `docker logs`. Output streams directly to your terminal; Ctrl-C t
1253
1253
  | `--follow, -f` | Stream indefinitely. |
1254
1254
  | `--tail <n>` | Lines from the end of the logs (default 200). |
1255
1255
 
1256
- ### `metabase workspace url <id>`
1256
+ ### `mb workspace url <id>`
1257
1257
 
1258
1258
  ```sh
1259
- metabase workspace url 1
1260
- metabase workspace url 1 --json
1259
+ mb workspace url 1
1260
+ mb workspace url 1 --json
1261
1261
  ```
1262
1262
 
1263
1263
  Prints `http://localhost:<port>` for the workspace's container. Reads the host port from the container's `com.metabase.workspace.host-port` label.
1264
1264
 
1265
- ### `metabase workspace credentials <id>`
1265
+ ### `mb workspace credentials <id>`
1266
1266
 
1267
1267
  ```sh
1268
- metabase workspace credentials 1
1269
- metabase workspace credentials 1 --json
1268
+ mb workspace credentials 1
1269
+ mb workspace credentials 1 --json
1270
1270
  ```
1271
1271
 
1272
1272
  Reads the workspace child's admin credentials (email, password, admin API key) from `/mw-config/credentials.json` inside the container. The file is written by `workspace start` from CLI-generated, per-workspace values; the same values are injected into `config.yml`'s `:users` and `:api-keys` sections so they take effect on the child's first boot. Works against running and stopped containers (uses `docker cp`); errors clearly if no container exists for the given workspace id. Removing the container destroys the file — recover by `workspace start <id> --force`.
1273
1273
 
1274
- ### `metabase workspace ps`
1274
+ ### `mb workspace ps`
1275
1275
 
1276
1276
  ```sh
1277
- metabase workspace ps
1278
- metabase workspace ps --json
1277
+ mb workspace ps
1278
+ mb workspace ps --json
1279
1279
  ```
1280
1280
 
1281
1281
  Lists every container that carries the `com.metabase.workspace.id` label, running or stopped. The `--json` envelope is the canonical agent-facing shape and contains only `workspace_id`, `workspace_name`, `state`, and `url`; `--full --json` emits the wider record (image, profile, parent URL, container name, status string, host port).
@@ -1284,14 +1284,14 @@ Lists every container that carries the `com.metabase.workspace.id` label, runnin
1284
1284
 
1285
1285
  Operations against a workspace-instance Metabase. The setup wizard and API key creation are distinct endpoints — there is no shared body schema.
1286
1286
 
1287
- ### `metabase setup`
1287
+ ### `mb setup`
1288
1288
 
1289
1289
  Complete the initial setup wizard (`POST /api/setup`). The body must include the setup token, the default user, and the `prefs` block (with `site_name`).
1290
1290
 
1291
1291
  ```sh
1292
- cat setup.json | metabase setup
1293
- metabase setup --file setup.json
1294
- metabase setup --body '{"token":"<setup-token>","user":{"email":"a@b.c","password":"..."},"prefs":{"site_name":"Acme"}}'
1292
+ cat setup.json | mb setup
1293
+ mb setup --file setup.json
1294
+ mb setup --body '{"token":"<setup-token>","user":{"email":"a@b.c","password":"..."},"prefs":{"site_name":"Acme"}}'
1295
1295
  ```
1296
1296
 
1297
1297
  | Flag | Description |
@@ -1299,14 +1299,14 @@ metabase setup --body '{"token":"<setup-token>","user":{"email":"a@b.c","passwor
1299
1299
  | `--body <json>` | Inline JSON body. |
1300
1300
  | `--file <path>` | Path to JSON body file. |
1301
1301
 
1302
- ### `metabase api-key create`
1302
+ ### `mb api-key create`
1303
1303
 
1304
1304
  Create a new API key (`POST /api/api-key`). The unmasked key is returned on creation only; capture it from the output.
1305
1305
 
1306
1306
  ```sh
1307
- metabase api-key create --name deploy-bot --group-id 2
1308
- echo '{"name":"k","group_id":2}' | metabase api-key create
1309
- metabase api-key create --file key.json
1307
+ mb api-key create --name deploy-bot --group-id 2
1308
+ echo '{"name":"k","group_id":2}' | mb api-key create
1309
+ mb api-key create --file key.json
1310
1310
  ```
1311
1311
 
1312
1312
  | Flag | Description |
@@ -1320,14 +1320,14 @@ metabase api-key create --file key.json
1320
1320
 
1321
1321
  Endpoints commonly used by agents driving the instance. `card query` and `transform run` are documented in their own sections; the helper below covers entity-id translation.
1322
1322
 
1323
- ### `metabase eid translate`
1323
+ ### `mb eid translate`
1324
1324
 
1325
1325
  Translate string entity ids (EIDs) to numeric ids (`POST /api/eid-translation/translate`).
1326
1326
 
1327
1327
  ```sh
1328
- metabase eid translate --model card --eids abc123XYZ,def456ABC
1329
- metabase eid translate --file translate.json
1330
- metabase eid translate --body '{"entity_ids":{"card":["abc123XYZ"]}}'
1328
+ mb eid translate --model card --eids abc123XYZ,def456ABC
1329
+ mb eid translate --file translate.json
1330
+ mb eid translate --body '{"entity_ids":{"card":["abc123XYZ"]}}'
1331
1331
  ```
1332
1332
 
1333
1333
  | Flag | Description |
@@ -1339,17 +1339,17 @@ metabase eid translate --body '{"entity_ids":{"card":["abc123XYZ"]}}'
1339
1339
 
1340
1340
  ## Query
1341
1341
 
1342
- ### `metabase query`
1342
+ ### `mb query`
1343
1343
 
1344
1344
  Run an MBQL 5 query with built-in schema validation. Three modes — discover the schema (`--print-schema`), validate without sending (`--dry-run`), run.
1345
1345
 
1346
1346
  MBQL 5 bodies use numeric IDs (`database: 1`, `source-table: 7`) and POST to `/api/dataset`. The bundled query schema is synced from `@metabase/representations`; `id.yaml` is overridden to require positive integers for every ID `$def`.
1347
1347
 
1348
1348
  ```sh
1349
- metabase query --print-schema # JSON Schema bundle
1350
- cat q.json | metabase query --dry-run # validate, no network
1351
- metabase query --file q.json
1352
- metabase query --file q.json --skip-validate # bypass pre-flight; let server reject
1349
+ mb query --print-schema # JSON Schema bundle
1350
+ cat q.json | mb query --dry-run # validate, no network
1351
+ mb query --file q.json
1352
+ mb query --file q.json --skip-validate # bypass pre-flight; let server reject
1353
1353
  ```
1354
1354
 
1355
1355
  Body sources: `--file`, `--body`, or stdin (exactly one). Body is JSON.
@@ -1373,11 +1373,11 @@ Output by mode:
1373
1373
 
1374
1374
  ### MBQL 5 pre-flight in `card create`/`update`, `transform create`/`update`, `measure create`/`update`, and `segment create`/`update`
1375
1375
 
1376
- When the embedded query (`card.dataset_query`, `transform.source.query` for `source.type: "query"`, or `measure.definition` / `segment.definition`) is MBQL 5 (`lib/type: "mbql/query"`), it is pre-flight-validated against the same schema as `metabase query`. Validation failure: `{ ok, errors }` envelope on stdout, exit 2, request not made. MBQL 4 (legacy) bodies and Python transform sources skip validation — they're still accepted by the server and we don't ship a schema for them.
1376
+ When the embedded query (`card.dataset_query`, `transform.source.query` for `source.type: "query"`, or `measure.definition` / `segment.definition`) is MBQL 5 (`lib/type: "mbql/query"`), it is pre-flight-validated against the same schema as `mb query`. Validation failure: `{ ok, errors }` envelope on stdout, exit 2, request not made. MBQL 4 (legacy) bodies and Python transform sources skip validation — they're still accepted by the server and we don't ship a schema for them.
1377
1377
 
1378
- Pass `--skip-validate` to bypass the pre-flight on any of `card create`, `card update`, `transform create`, `transform update`, `measure create`, `measure update`, `segment create`, or `segment update` — the body is sent as-is and the server is the authority. Same escape hatch as on `metabase query`; use only when the bundled schema disagrees with what the server actually accepts.
1378
+ Pass `--skip-validate` to bypass the pre-flight on any of `card create`, `card update`, `transform create`, `transform update`, `measure create`, `measure update`, `segment create`, or `segment update` — the body is sent as-is and the server is the authority. Same escape hatch as on `mb query`; use only when the bundled schema disagrees with what the server actually accepts.
1379
1379
 
1380
- Agent discovery path: `metabase __manifest` lists every command's args and description; the description for `card create`/`update`, `transform create`/`update`, `measure create`/`update`, and `segment create`/`update` references `metabase query --print-schema` so an agent can fetch the validating schema directly.
1380
+ Agent discovery path: `mb __manifest` lists every command's args and description; the description for `card create`/`update`, `transform create`/`update`, `measure create`/`update`, and `segment create`/`update` references `mb query --print-schema` so an agent can fetch the validating schema directly.
1381
1381
 
1382
1382
  The bundled query schema is synced from a pinned `@metabase/representations` release via `bun run sync:representations`; CI guards against drift.
1383
1383
 
@@ -1391,15 +1391,15 @@ If the chained `PUT /api/dashboard/:id` fails _after_ the create has already ins
1391
1391
 
1392
1392
  ## UUIDs
1393
1393
 
1394
- ### `metabase uuid`
1394
+ ### `mb uuid`
1395
1395
 
1396
1396
  Mint UUID v4 strings (Node `crypto.randomUUID`) for MBQL clause `lib/uuid` slots, native template-tag ids, and any other Metabase-side identifier whose schema enforces RFC 4122 format. Agents must call this command to obtain UUIDs rather than authoring them by hand: the bundled MBQL 5 schema rejects placeholder strings (`a1`, `uuid-1`, etc.) at `format: "uuid"` validation.
1397
1397
 
1398
1398
  ```sh
1399
- metabase uuid # one UUID
1400
- metabase uuid --count 5 # five UUIDs, one per line (text mode in a TTY, JSON when piped)
1401
- metabase uuid --count 5 --json # explicit JSON: ["…", "…", "…", "…", "…"]
1402
- metabase uuid --count 5 --format text # explicit text: one UUID per line
1399
+ mb uuid # one UUID
1400
+ mb uuid --count 5 # five UUIDs, one per line (text mode in a TTY, JSON when piped)
1401
+ mb uuid --count 5 --json # explicit JSON: ["…", "…", "…", "…", "…"]
1402
+ mb uuid --count 5 --format text # explicit text: one UUID per line
1403
1403
  ```
1404
1404
 
1405
1405
  Output: text mode prints one UUID per line; JSON mode prints a `string[]`. Default behavior follows the standard `--format auto` rule — JSON when stdout is a pipe, text when it's a TTY.
@@ -1408,24 +1408,103 @@ Output: text mode prints one UUID per line; JSON mode prints a `string[]`. Defau
1408
1408
 
1409
1409
  Exit codes: `0` success, `2` invalid `--count`.
1410
1410
 
1411
+ ## Upgrade
1412
+
1413
+ ### `mb upgrade`
1414
+
1415
+ Self-update the CLI. Fetches the latest published version from the npm registry's `/-/package/<pkg>/dist-tags` endpoint, detects how the binary was installed (npm-global / npm-local / npx / dev / unknown — for the global case, also which package manager: npm, pnpm, yarn, or bun), and either runs the matching install command (for npm-style globals, after confirmation) or prints the exact command to run by hand.
1416
+
1417
+ ```sh
1418
+ mb upgrade # interactive: check + confirm + run for global installs
1419
+ mb upgrade --check # print status only, never install
1420
+ mb upgrade --check --json # structured plan for agents
1421
+ mb upgrade --yes # skip the confirmation prompt
1422
+ mb upgrade --to 0.1.2 # pin a specific version (also valid for downgrades)
1423
+ ```
1424
+
1425
+ Flags:
1426
+
1427
+ - `--check` — print the upgrade plan without installing.
1428
+ - `--yes` / `-y` — skip the confirmation prompt; only meaningful when the install method is auto-installable.
1429
+ - `--to <version>` — target a specific semver instead of the registry `latest`. Useful for pinning or rolling back.
1430
+ - `--registry <url>` — override the npm registry (default `https://registry.npmjs.org`). The same URL the CLI hits to fetch dist-tags; the actual install always goes through your local `npm` / `pnpm` / `yarn` / `bun` which use their own configured registry.
1431
+
1432
+ JSON output (UpgradeStatus):
1433
+
1434
+ ```json
1435
+ {
1436
+ "packageName": "@metabase/cli",
1437
+ "currentVersion": "0.1.2",
1438
+ "latestVersion": "0.1.3",
1439
+ "targetVersion": "0.1.3",
1440
+ "updateAvailable": true,
1441
+ "changeRequired": true,
1442
+ "installMethod": "npm-global",
1443
+ "packageManager": "npm",
1444
+ "binaryPath": "/usr/local/lib/node_modules/@metabase/cli/dist/cli.mjs",
1445
+ "command": {
1446
+ "argv": ["npm", "install", "-g", "@metabase/cli@0.1.3"],
1447
+ "display": "npm install -g @metabase/cli@0.1.3"
1448
+ },
1449
+ "canAutoInstall": true
1450
+ }
1451
+ ```
1452
+
1453
+ Auto-install happens only when `installMethod === "npm-global"`; everything else (local installs, npx, dev checkouts) prints the upgrade command and exits. In non-TTY runs without `--yes`, the command never prompts.
1454
+
1455
+ Exit codes: `0` success (including up-to-date / printed-instructions), `1` registry or install failure, `2` invalid `--to` value, `130` user cancelled the prompt.
1456
+
1457
+ ## Skills
1458
+
1459
+ The CLI ships with bundled agent skills (Claude Code / `npx skills add` compatible) that document `mb` itself. Content is served at runtime from the installed CLI version, so the instructions an agent fetches always match the binary it's about to run — no drift between a separately-installed skill copy and the CLI.
1460
+
1461
+ ```sh
1462
+ mb skills list # discover bundled skills (table or JSON)
1463
+ mb skills get core # print the top-level guide
1464
+ mb skills get core --full # include references and templates
1465
+ mb skills get workspace,transform # comma-separated, multi-skill fetch
1466
+ mb skills get --all --json --max-bytes 0 # every non-hidden skill, structured (default cap truncates)
1467
+ mb skills path # absolute paths for direct Read
1468
+ mb skills path core # one path
1469
+ ```
1470
+
1471
+ `mb skills get` honors the shared `--max-bytes` list cap. With the default 65 536 cap, `--all` will return only the first skill and emit a truncation notice — pass `--max-bytes 0` to dump every skill in one envelope.
1472
+
1473
+ Bundled skills:
1474
+
1475
+ | Name | Use |
1476
+ | ----------- | -------------------------------------------------------------------------------------- |
1477
+ | `core` | Top-level guide: auth, flag conventions, output flags, body input, every command group |
1478
+ | `workspace` | Enterprise workspace lifecycle (create, provision, start, child credentials, diagnose) |
1479
+ | `transform` | Authoring and running transforms (native SQL + MBQL 5), iteration, run inspection |
1480
+ | `git-sync` | Round-tripping Metabase content to/from a git remote |
1481
+
1482
+ Discovery surfaces:
1483
+
1484
+ - **Claude Code plugin marketplace**: `.claude-plugin/marketplace.json` declares a `metabase-cli` plugin pointing at the in-repo discovery stub. Users install with `/plugin marketplace add metabase/mb-cli` then `/plugin install metabase-cli@metabase`.
1485
+ - **`npx skills add`**: the same stub at `skills/metabase-cli/SKILL.md` is picked up by `npx skills add metabase/mb-cli`. The stub is intentionally minimal — it redirects the agent at `mb skills get core` so the real workflow content always comes from the installed CLI version.
1486
+
1487
+ Exit codes: `0` success, `2` `ConfigError` (missing name, unknown name, `MB_SKILLS_DIR` not a directory), `1` unexpected I/O.
1488
+
1411
1489
  ## Environment variables
1412
1490
 
1413
- | Variable | Effect |
1414
- | ------------------------ | ------------------------------------------------------------------------------ |
1415
- | `METABASE_URL` | Default URL for `auth login` and config resolution. |
1416
- | `METABASE_API_KEY` | Default API key (overrides interactive prompt; not stored). |
1417
- | `METABASE_PROFILE` | Default profile when `--profile` is omitted. Falls back to `default`. |
1418
- | `METABASE_LICENSE_TOKEN` | Default license token for `license set`. |
1419
- | `METABASE_VERBOSE` | When set to `1`, prints structured developer-detail JSON to stderr on failure. |
1491
+ | Variable | Effect |
1492
+ | ------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
1493
+ | `METABASE_URL` | Default URL for `auth login` and config resolution. |
1494
+ | `METABASE_API_KEY` | Default API key (overrides interactive prompt; not stored). |
1495
+ | `METABASE_PROFILE` | Default profile when `--profile` is omitted. Falls back to `default`. |
1496
+ | `METABASE_LICENSE_TOKEN` | Default license token for `license set`. |
1497
+ | `METABASE_VERBOSE` | When set to `1`, prints structured developer-detail JSON to stderr on failure. |
1498
+ | `MB_SKILLS_DIR` | Override the directory `mb skills` scans (dev/test only; defaults to the CLI's bundled `skills` + `skill-data` trees). |
1420
1499
 
1421
1500
  ## Agent integration
1422
1501
 
1423
- ### `metabase __manifest`
1502
+ ### `mb __manifest`
1424
1503
 
1425
1504
  Hidden command that emits a machine-readable JSON manifest of every leaf command — name, description, examples, citty args, and the output Zod schema rendered as JSON Schema. Intended for agents that need typed capability discovery instead of scraping `--help`.
1426
1505
 
1427
1506
  ```sh
1428
- metabase __manifest | jq '.commands[].command'
1507
+ mb __manifest | jq '.commands[].command'
1429
1508
  ```
1430
1509
 
1431
1510
  The manifest schema (`Manifest`) is exported from `src/runtime/manifest.ts`.