* Declare png and gif module imports for the bundler
* Hash onboarding, upsell and example images through the build
* Assert the Slack app icon link against the bundled asset
* Hash the upsell card story illustration through the build
* Take image sources as props instead of building paths from a base string
* Add a ?url image import that the SDK bundle references instead of inlining
* Hash empty state, upsell and driver logo images through the build
* Hash the map skeleton sprite and the bridge illustration through the build
* GDGT-3128: Pin browserslist to the versions we actually support
The documented floor (Chrome 70, Firefox 68, Edge 17, Safari 11) had drifted
far from reality. Auditing the shipped bundles turned up features that break
well above it:
- subgrid (Chrome 117), unguarded in two CSS modules
- :has() (Firefox 121), 248 occurrences; the postcss polyfill is disabled
- color-mix() (Chrome 111), including the ui/colors base palette
- toSorted/findLast (Safari 16.4) and URL.canParse (Chrome 120, Safari 17)
There are no polyfills to fall back on: core-js is not a dependency, so
preset-env injects nothing.
browserslist said "defaults", which resolves to Chrome 109 among others --
below our own floor -- so the build was targeting browsers the code breaks
on. Pin it to the audited versions instead.
The rspack swc-loaders hardcoded env.targets: ["defaults"], bypassing
package.json entirely. Dropping targets lets swc fall back to the
browserslist config, matching babel-loader and postcss.
Verified against the real postcss pipeline over all 826 CSS files. Prefix
output only improves: -webkit-backdrop-filter is now emitted (Safari needs it
through 17.6, and it was previously missing), and -webkit-background-clip is
dropped, which is safe because Chrome 120 is exactly where the unprefixed
form lands. The -moz-column-*/-o-* prefixes that go away were for Firefox
versions far below 121.
* GDGT-3128: Use the :global() function form in CSS modules
Pinning browserslist dropped `op_mini all` from the targets, and Opera Mini
was the only thing keeping postcss-preset-env on its expanded nesting
desugaring. With it gone, preset-env emits the spec-correct `:is()` form:
.editor :global .cm-panels -> :is(.editor :global) .cm-panels
That pulls `:global` inside `:is()`, where its positional "everything after
this is global" semantics no longer apply. css-loader then scoped the classes
it was meant to leave alone:
:local(.editor) .cm-panels -> :is(:local(.editor)) :local(.cm-panels)
CodeMirror renders real `.cm-editor`/`.cm-panels`/`.cm-content` elements, so
every rule in those blocks silently stopped applying -- 20 scoped selectors and
0 global in CodeMirror.module.css alone. That took out three e2e specs:
cc-typing-suggestion, native-reproductions and transforms.
The `:global()` function form binds global-ness to a selector node instead of a
position, so no amount of selector rearrangement can separate it from the class.
Verified to hold three levels deep, including under `:is()` wrapping.
Selector output is otherwise unchanged: compiling each file under the old and
new configs and comparing the post-CSS-modules selector sets gives an exact
match, except for a `::-moz-placeholder` that the browserslist pin drops on its
own (Firefox 121 has it unprefixed).
The stylelint rule catches the bare form. It also flags a top-level `:global {}`
block, which happens to work today only because a lone `:global` is a single
compound and escapes the `:is()` wrap -- one more nesting level and it breaks
the same way.
* GDGT-3128: Raise the Safari floor to 18.2 for auxclick
`auxclick` lands in Safari and iOS Safari 18.2 -- every version through 18.1
reports `n` in caniuse. There are 12 unguarded `onAuxClick` handlers in app
source (19 counting tests), so 17 was never a floor we actually met.
Chrome (55), Firefox (53) and Edge (79) are all far below their current floors,
so only Safari moves.
Side effect: `-webkit-backdrop-filter` is no longer emitted. Safari needed it
only through 17.6, so past 18.2 autoprefixer correctly drops it. The same bump
also covers scrollbar-gutter/width/color, which all wanted exactly Safari 18.2.
* Clean up leftover JS-era config, deps, and docs after the TypeScript migration
* Address review: keep .jsx in resolve.extensions, drop .js from loader tests, includes-based e2e validator filter
* Keep @babel/node for a separate deps cleanup round
* Keep js/jsx in rspack loader tests
* Load CodeMirror editors lazily so they leave the initial bundle
* Inline the single-use dynamic imports into the lazy calls
* Share the codemirror split chunk with the embedding SDK build
* Split the snippet, Python and public document pages by route instead of wrappers
* Dedupe modules shared by async chunks instead of naming CodeMirror
* Drop the duplicate metrics viewer route that master already added
* Keep barrel imports and mark the expression language side-effect free
* Move the action editor boundary to the new action-creator module
* Drop the codemirror cache group the SDK config no longer needs
* Drop props types exported for wrappers that route splitting replaced
* Delay the code fallback so a fast chunk load never flashes uncoloured code
* Render nothing while the code editor chunk loads
* Delay the whole expression widget instead of showing a spinner inside it
* Open the editors from routes and modals instead of loading states
* Fold the Metabot preview chunk into the message's own loading state
* Fold the query editor chunk into the transform pages' own loading state
* Prefetch the expression widget from the notebook so its popovers open ready
* Await the run error message now that the code editor loads lazily
* Hold the custom column popover shut until the expression widget arrives
* Wait for the expression editor to hold focus before typing into it
* Type into the page directly when asserting the read-only native editor
* Read the editor value only once its document stops changing
* Mark metabase/router as side-effect free for rspack
* Route deep metabase/router imports through the barrel
* Let static-viz import the router barrel instead of a deep module
* Guard the side-effect-free contract and scope the include to the directory
* initial proof-of-concept for data apps
POC 2
POC 3
POC 4
Revert "POC 4"
This reverts commit 1f62e574dc.
POC 5
POC 6
* Expose all SDK components to child realm
* Setup app publishing and serving
* Refactor distortion helpers
* Adjust skill
* Add useQuestionQuery SDK hook (#74900)
Co-authored-by: Timofei <timofei@metabase.com>
* Mock METABASE_EMBEDDING_SDK_BUNDLE for data app sdk hooks/components
* Adjust skill for TS project
* Update skill to clearly mention TS
* Add blocked APIs list to skill
* Prototype schema exports and typed hooks for custom data apps (#74978)
* add prototype for schema generation
* add formatting for generated schemas
* add skill file
* useQuestionQuery should take only ID based on @sanex3339 feedback
* add segments, measures, tables and useMetabaseQuery hook
* Add useMetabaseQuery to endowments
* Fix queryDataset
---------
Co-authored-by: Timofei <timofei@metabase.com>
* Add ability to update app bundle
* Simplify hook
* Add spinner instruction
* Mode Data Apps to OSS
* Instruct to not not use blocked event handlers
* Improve API, add styles isolation, add router components (#75418)
* Prepare skills for data app template + adjust router components (#75490)
* Fixes after rebase
* Move migration to v63
* Move migration to v63 #2
* Fix config.edn
* Fix BE tests
* Fix team name
* Fix duplicated config
* Adjust version text in skill
* Fix data app bundle uploading after legacy client removal
* Remove `actions` from config edn
* Fix failing test
* Fix failing test #2
* Add custom actions for data apps (#75627)
* Fix imports
* Fix type annotations
* Adjust migration
* Adjust permissions
* Fixed iframe security
* Data Apps publishing via remote repository POC (#75702)
* Update gitignore with data-app.html
* [PoC] Type safety and modularity improvements for custom data apps (#75381)
* allow separate libraries in schemas
* add metric type checking
* add collections parameter
* check that segments and measures belongs to table in useMetabaseQuery
* require less type information for measures
* require less type information for segments
* use metric dataset endpoint when querying measures in metrics
* add validation for breakout buckets
* fix filter operation type scoping
* expose filter type helper for nicer autocompletions
* update skill file
* add breakout schema helper for better type errors
* update breakout schema helper to accept binning and bucket
* move fields that are not used in compile and runtime to comments to shorten type errors
* enforce data truthfulness in skill
* enforce semantic layer richness in skill
* handle dimension key collisions mapped from many tables
* update skill description
* prevent hallucinated measures and breakouts
* fix field serialization
* add guidance on using filter matcher
* add skill guidance on long results and units
* accept query object in StaticQuestion and InteractiveQuestion
* extract use-metabase-query to multiple files
* update skill file to use sdk question by default
* update skill file to avoid hallucinated derived calculations
* add new functions into sandbox
* kondo and cljfmt lint fixes
* update CSP rules to allow style tags for data apps
* address review feedback on scoping and metric filters
* address code review feedback
* Add aggregations support for breakouts in query hooks (#75723)
* add aggregations support
* add additional aggregation helpers
* Add metrics support in useMetabaseQueryObject hook (#75728)
* add metric queries
* indicate metric support in skill file for useMetabaseQueryObject
* add new version for release
* fix query dataset tests
* update release workflow temporarily
* update skill description
* update skill to use more generic examples
* hotfix: allow esm usage in vite dev mode
* skill file update for table caveat
* update sandbox
* fix type errors in useMetabaseQuery
* add v0.63.2 to release workflow
* update skill file to use the 63-data-apps version
* Move data apps to the EE directory and under `data-apps` token feature (#75871)
* remove skill file alias
* Add error handling for data apps
* Add spinner while iframe is loading
* Add OSS/no token upsell banner placeholder for data apps (#75893)
* ensure a fixed height is set if container has height
* Allow including everything in data and metric library in schema endpoint (#75944)
* add filter for including library and data collections
* address review on skill file
* remove id field from rendered comment
* remove useQuestionQuery and useMetricQuery hook
* Improve env files lookup in skills (#75955)
* Allow `unsafe-eval` for data app iframe (#76004)
* Fix lint
* Fixes after rebase
* Fix duplicated test
* Improve Providers and typesafety (#75934)
* chore: reformat single expression functions to arrow
* Use entity id in questionCollections when generating typed schemas (#76230)
* allow using entity ids for question collection filter
* guide the agent towards using entity ids
* add failing test for invalid entity id
* Make custom viz work in data apps (#76237)
* Allow blob: images in data-app CSP (EMB-1923)
SDK custom visualizations load their icon assets via blob: URLs (to avoid
the cross-origin auth issue), but the /embed/data-app/ route allowed
'unsafe-eval' without the blob: scheme in img-src, so icons were blocked
under a production CSP. Add blob: to img-src scoped to the data-app iframe
route only; the main app img-src stays strict.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* EMB-1880: support for `providerProps` in data apps
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Reduce schema bloat in dimensions of generated metrics when many tables are involved (#76003)
* Add useQuestionQuery SDK hook (#74900)
Co-authored-by: Timofei <timofei@metabase.com>
* Prototype schema exports and typed hooks for custom data apps (#74978)
* add prototype for schema generation
* add formatting for generated schemas
* add skill file
* useQuestionQuery should take only ID based on @sanex3339 feedback
* add segments, measures, tables and useMetabaseQuery hook
* Add useMetabaseQuery to endowments
* Fix queryDataset
---------
Co-authored-by: Timofei <timofei@metabase.com>
* [PoC] Type safety and modularity improvements for custom data apps (#75381)
* allow separate libraries in schemas
* add metric type checking
* add collections parameter
* check that segments and measures belongs to table in useMetabaseQuery
* require less type information for measures
* require less type information for segments
* use metric dataset endpoint when querying measures in metrics
* add validation for breakout buckets
* fix filter operation type scoping
* expose filter type helper for nicer autocompletions
* update skill file
* add breakout schema helper for better type errors
* update breakout schema helper to accept binning and bucket
* move fields that are not used in compile and runtime to comments to shorten type errors
* enforce data truthfulness in skill
* enforce semantic layer richness in skill
* handle dimension key collisions mapped from many tables
* update skill description
* prevent hallucinated measures and breakouts
* fix field serialization
* add guidance on using filter matcher
* add skill guidance on long results and units
* accept query object in StaticQuestion and InteractiveQuestion
* extract use-metabase-query to multiple files
* update skill file to use sdk question by default
* update skill file to avoid hallucinated derived calculations
* add new functions into sandbox
* kondo and cljfmt lint fixes
* update CSP rules to allow style tags for data apps
* address review feedback on scoping and metric filters
* address code review feedback
* Add aggregations support for breakouts in query hooks (#75723)
* add aggregations support
* add additional aggregation helpers
* Add metrics support in useMetabaseQueryObject hook (#75728)
* add metric queries
* indicate metric support in skill file for useMetabaseQueryObject
* add new version for release
* fix query dataset tests
* remove useQuestionQuery and useMetricQuery hook
* Data Apps publishing via remote repository POC (#75702)
* avoid duplicating dimension fields
namespace dimensions by table
add dimension id to mapping
pick from table fields for only allowed dimensions
fix incorrect type guards
allow querying metric using question as source
remove createMetabaseQuery from public interface
add sourceFieldId to metric
* doc generation type fixes
---------
Co-authored-by: Timofei <timofei@metabase.com>
* Add allowed hosts handling for data apps (#76094)
* Update version
* Properly include data app changes in `pull changes` modal (#76294)
* Move app template into main repo, handle skill versioning flow (#76288)
* feat(data-apps): allow passing down a card with viz settings (#75993)
support card prop in sdk question component
* Rename data app env variables and read them only in dev mode (#76604)
* Add custom data apps layout with sliding toolbar (#76600)
* Remove unused helper
* Dev env Sandboxing, Human Readable Errors and Copy Helper (#76597)
* Revert wrong rebase changes
* Improve creating filtering interfaces in custom data apps (#76401)
* update skill files to guide filter usages
* update skill file to prevent filtering mistakes
* move filtering ui patterns into a separate file
* do not treat mb_replace_me as valid creds
* use combobox for filters
* pass title false to sdk question
* combobox trigger before typing
* Add missing exported types
* Apply visualizations and visualization settings from SDK package (#76659)
* ask the agent to pull possible visualizations
* ask the agent to use card prop
* teach the agent when to use viz settings
* Support query-only SDK cards
* Remove cross references between data apps skills (#76661)
Remove data app skill cross references
* Move Data App Dev Vite App setup into SDK package (#76695)
* Don't navigate on ad-hoc question chart clicks (#76751)
* Fix sandboxing crashes and update skill file mistakes (#76858)
Fix data app sandboxing and skill guidance
* Block form submissions in data apps via CSP (#76882)
* Fix SDK theming hover text colors in generated data apps (#77083)
update guidance on colors
* Remove SDK question query prop for data apps use cases (#77080)
* Remove SDK question query prop
* update tests to use card prop instead
* Adopt Lib.createTestQuery for table sources when querying in data apps (#75957)
* Add base metabase-lib query implementation
* switch to Lib.createTestQuery DSL
* Load query metadata at runtime for metabase-lib instead of hard-coding (#76874)
* load query metadata dynamically
* accept id-only source references
* Wait for SDK login before resolving query metadata
* refactor: use useAsyncFn to handle states
* pass source-name to createTestQuery
* Add metric aggregations for useMetabaseQuery via Lib.createTestQuery (#76947)
* add metric sources for useMetabaseQuery via Lib.createTestQuery
* use MetabaseQueryObject instead of opaque type marker
* Fix metric schema and join source validation
* add metric library filtering to skill files
* make metric an aggregation expression instead of join sources
* mark tableId as never in joined fields
* export public MetabaseQueryObject type
* use camelCase for source name and field id
* Add initial data app e2e setup (#77101)
* Add sorting and fields to useMetabaseQuery via Lib.createTestQuery (#76966)
* add sorting, limiting and fields to useMetabaseQuery
* refactor: cleanup sorting and aggregations
* Fix metric order by validation
* Support saved questions for useMetabaseQuery via Lib.createTestQuery (#77073)
* add saved questions as useMetabaseQuery input
* remove extra operators for saved cards
* Add unit fe/be tests for data apps (#76979)
* Fix lint
* Use modern api in query-dataset.ts
* Fix BG color
* Fix execute-action tests
* Update SDK-data-apps version
* Move migrations to v64 folder
* Adjust router components to use metabase/router
* Allow opening a data app for any signed user
* Rename data app skills (#77266)
* Update DataAppLayout.tsx `go back` button logic
* Harden data apps skills and action validation errors (#77261)
* harden data apps skills and actions error validation
* do not display models as questions in data apps
* clarify action result types
* Agents should report errors when models, actions or questions cannot be schema generated (#77260)
* return an error if models or saved questions are invalid
* return an error if actions are invalid
* update skill file guidance on model generation
* fix model boundary
* Add data apps admin UI + routing/sandboxing/isolation e2e (#77271)
* Rename data-apps paths to /apps (#77298)
* Include all action-included models in the typed schema when a mutation is specified (#77291)
* add includeModels=true flag to include all models
* omit model columns and models without actions
* remove extra metadata
* Adjust admin UI for Data Apps (#77420)
* Add more e2e/unit tests for Data Apps (#77524)
* Update bun.lock
* Fix errors after rebase
* Parallelize dts rollup (#77663)
* revert EMB-1840 measures support in metric dataset endpoint
* chore: add data app module (#77705)
* test ci
* apply code review suggestion
* Setup separate entries for client and node dev data app entries (#77687)
* Fix type casts lint errors (#77696)
* Adjust data apps setup + add proper analytics setup (#77604)
* Extract common and scope helpers + tests for typed schema module (#77403)
* refactor: extract common and query param helpers
* refactor: use kebab-case for query params
* refactor: cleanup schema mapping
ci: fix module config
* refactor: rename schema scope helpers to scope.clj
* refactor: extract scope_test.clj
* Extract typed schema rendering helpers to render.clj (#77703)
* extract schema render function
* move runtime compact test out
* remove javascript and json endpoints from schema generator
* refactor: cleanup javascript.clj and render.clj
* Extract typed schema generators for tables and questions (#77729)
* refactor: extract schema generator modules
* remove question-details from model-schemas
* fix: batch queries in table and question schema generator
* remove N+1 in typed schema field table lookup
* Extract typed schema generators for models and actions (#77739)
* extract model schema generator
* batch model action querying to avoid n+1 queries
* Extract typed schema generator for metrics (#77806)
* Extract typed schema generators for models and actions (#77739)
* extract model schema generator
* batch model action querying to avoid n+1 queries
* extract metric schema generator
* test: simplify fields in metric_test fixtures
* refactor: clean up metric schema generation
* remove n+1 from metric field dimension read
* disable default temporal dimension breakout
* surface errors if metric schema cannot be built
* revert metrics/api.clj to master to remove outdated comments
* Fix routes
* Take a data app's slug from its directory name (#77688)
* Merge data-apps specific migrations into one
* ci: fix failing backend test and cljfmt lint
* Add a beta badge in data apps admin page heading (#77877)
marks the data app as beta
* Revert "Merge data-apps specific migrations into one"
This reverts commit 383a5fa28d.
* Revert "Revert "Merge data-apps specific migrations into one""
This reverts commit 948d904b62.
* ci: actionlint fix
* Fix data apps route
* Use getSubpathSafeUrl in attachIframeUrlMirror
* Fix comment
* Do not send apps with sync error for token check
* Add data app listing sidebar section for non-admins (#77977)
* show data apps in sidebar for non-admins
* add app icon to data apps
* use available=true to filter no sync error and enabled apps
* fix navbar keys in data apps
* test: use non-admin user to assert non-admin response
* fix toucan query in data apps listing endpoint
* re-export entity detail helpers and result column to metabot core
* open data apps in new tab from the sidebar
* Prevent race conditions in responses of useMetabaseQuery hook (#78023)
prevent stale responses in useMetabaseQuery
* ci: remove tools.util from module declaration
* Merge migrations into a single one
* reset release-embedding-sdk.yml to master
---------
Co-authored-by: Phoomparin Mano <poom@metabase.com>
Co-authored-by: Phoomparin Mano <phoomparin@gmail.com>
Co-authored-by: Nicolò Pretto <info@npretto.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Emit frontend bundle stats from production build
* Track bundle sizes over time in stats.metabase.com
* Fix formatting
* Remove unused lint rule
* Reuse measure-bundle-sizes.js in the SDK bundle size check
Disable rspack lazy compilation in dev to fix broken visualizations
rspack-cli 2.0 auto-enables lazyCompilation for web-only targets. Its
trigger XHR uses a relative URL, so requests hit the backend (:3000)
instead of the dev server (:8080) and 500, leaving lazily-imported
modules uncompiled. Opt out explicitly to restore rspack 1.x behavior.
* Convert metabase/utils files to TypeScript, part 2 (#72679)
* Convert metabase/utils spec files to TypeScript, part 2
* Remove some type castings
* Convert memoize.unit.spec.js > ts
* fix(sdk,embed-js): Refactor query handling to show aggregations/breakout for the last non-empty stage (#72219)
* Merge `metabase-lib/v1/utils/card` and `metabase/utils/card` into `metabase/common/utils/card` (#72609)
* Rename isTransientId to isTransientCardId for clarity
* Move metabase-lib/v1/utils/card into metabase/utils/card
* WIP
* Fix card comparison types
* Move metabase/utils/card to metabase/common/utils/card
* Fix lint
* Add ts expect error for unknown card usage
* Fix import order
* Allow passing other values to isTransientId
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Fix spacing issue
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Colocate isTransientCardId with Question to fix import loop
* Be more lenient as to what card can be
* Remove dead code branch
* Fix formatting
* Fix applyParameters helper
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Refactor breakout handling to utilize custom query handlers (#73093)
* feat: MCP Apps implementation for visualizing queries
Adds MCP Apps endpoint for visualizing ad-hoc queries via the Embedding SDK.
Backend:
- MCP JSON-RPC endpoint at /api/mcp (SSE + HTTP streaming)
- Session management with TTL sweep and scope-based auth via OAuth bearer tokens
- resources/list + resources/read handlers serving embed-mcp.html
- Short-lived embedding sessions created per resources/read, cleaned up on MCP teardown
- visualize_query tool returning structuredContent.query (base64 MBQL)
- EE tools/manifest generated from agent API endpoint metadata
- Embedded OAuth/OIDC provider for MCP authentication (moved to OSS)
- DCR default-scope injection for MCP clients that omit scope during registration
- skip-frame-ancestors CSP option for SDK embed route
Frontend:
- app-embed-mcp.tsx entrypoint + McpUiAppRoute component
- Uses embedding-sdk-package (MetabaseProvider + InteractiveQuestion) as a
plain SDK consumer — no internal SDK coupling
- MCP postMessage protocol: ui/initialize, host-context, tool-input, tool-result
- CSS variable resolution for MCP hosts (VSCode sends var(...) references)
- Safe area insets + dark/light theme fallbacks
- embed-mcp.html Mustache template with stable filename (no content hash)
- sessionToken auth config type added to SDK
- Removes metabase-adhoc custom element and AdHocQuestion public component
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
add mark session initialized
add agent:visualize as an extra OAuth tool scope
fix instance url in embed-mcp template
use component provider instead of metabase provider
fix component provider implementation
avoid layout shift via fixed height
add automatic sizing
hide editor button in MCP Apps view
add simple loading indicator
revert sessionToken changes as we now inject it directly
remove useless CSS variables injection
remove useless sessionToken in template
comment the colors
refactor: extract color transformer
add tests for color transformer
fix chunks
remove the unneeded connect domains
revert session-for-user
secure the agent:visualize scope
remove unneeded eslint exception
fix CSS variables lint
declare that mcp uses session module
add withEditorButton to schema
Inline site-url and avoid double call
Restore detailed comment for MCP app HMR exclusion
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
skip sdk checks for mcp apps
skip EE auth flow for MCP Apps
revert prettier changes
support vscode and cursor colors
Declarative UI tool registration (#71568)
address review: remove enableEmbeddingSettingKey
rename useMcpTheme to buildMcpAppsTheme (not a hook)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
skip spec files in CSS variable script, remove stale whitelist entries
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
add linear task id on analytics header
migrate useMcpApp to @modelcontextprotocol/ext-apps
Replaces hand-rolled JSON-RPC postMessage implementation with the
official ext-apps library. The lib handles protocol versioning,
ResizeObserver auto-resize, and CSS variable/font application.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
add tsconfig paths for @modelcontextprotocol/ext-apps subpaths
moduleResolution:node doesn't support package.json exports field,
so we need explicit path aliases for the /react subpath.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
use ambient module declaration for @modelcontextprotocol/ext-apps subpaths
Replaces tsconfig paths aliases with a declaration file in frontend/src/types/,
consistent with how other third-party module types are handled in the project.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
cleanup types in useMcpApp
fix theme switching by using imperative style application
The useHostStyleVariables and useHostFonts hooks each overwrite
onhostcontextchanged, so only the last one registered would fire.
Switch to imperative applyDocumentTheme/applyHostStyleVariables/
applyHostFonts calls within a single handler to fix live updates.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
bump @modelcontextprotocol/ext-apps to 1.3.2
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
use HtmlWebpackPlugin for MCP app template instead of manual cache busting
The MCP app HTML was previously a hand-written Mustache template with
hardcoded script/link references and manual ?v= cache busting. This
required several rspack config hacks: stable filenames (no content hash),
runtime: false, chunk exclusion from splitChunks, and a CSS filename
override.
Now the MCP app uses HtmlWebpackPlugin like all other entry points.
The template (mcp_apps_template.html) contains only MCP-specific
markup and Mustache vars, while HtmlWebpackPlugin injects script/link
tags with content hashes at build time. A Mustache variable in the
HtmlWebpackPlugin publicPath ({{{instanceUrlRaw}}}/app/dist/) is
emitted literally at build time and resolved by Stencil at runtime,
working around the srcdoc iframe's about:srcdoc origin and CSP
base-uri restriction.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Stateless MCP sessions (#71819)
* remove incorrect rebase changes
* Expand `construct_query` MCP tool description
The tool previously shipped with a ~430-char description and a 12KB
auto-generated JSON schema. That's enough for the LLM to see what's
valid structurally, but not enough to know which idioms are canonical —
so agents routinely produced non-canonical shapes (field-options in a
third slot, bare aggregated sort refs, no `append-stage` before
filtering on aggregations).
Extract the description into a `construct-query-tool-description` def
that covers source types, every top-level operation, the nested
reference forms (including `with-temporal-bucket` and `with-binning`),
filter/aggregation/temporal operator names, and four worked examples
(top-N, metric with monthly bucket, filter-on-aggregated with
`append-stage`, named expression). Stops short of the full agent_api
reference; aims for enough structure to write valid programs without
guessing.
* Add workflow and pitfalls sections to `construct_query` description
Expand the `construct_query` MCP tool description with the guidance
agents consistently get wrong: the workflow (fetch entity detail →
construct → execute/visualize), an `offset` example where
`append-stage` must NOT be added, and a rules section sourced from the
capability catalog's `prompt-notes` covering stage boundaries,
ref/shape constraints (aggregation-ref for sorting, no third-slot
field options, bare `case` fallback, JSON objects only where helpers
explicitly call for them), when to prefer direct related-field refs
over explicit joins, and metric/date caveats.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Trigger new charts through some drill-through actions (#73278)
Trigger new charts through drills and show question title
adjust interactivity patterns for mcp apps
add prototype for query name + context
add sorting as stay drill
update stay drills
add prototype for bars
add prototype for time range picker
prototype: default to table and do not trigger if no breakouts/aggregations
make prompt more assertive
inject encoded query as structured content
prototype: custom question title
store pending cards and use render_drill_through tool call
experiment: question titles
remove duplicated query bar logic
refactor: move mcp question title out
always show the question title for drills
extract a query stage friendly utility
cleanup the query description proof-of-concept
refactor: use the extracted query explorer bar
cleanup: remove mcp debugging hook
add table visualization to query explorer bar
do not show query bar if there is ONLY tables
add extra top padding
style adjustments
cleanup unused mcp-dev endpoints
use PATCH /api/mcp/ui/drills endpoint
use POST instead of PATCH
type fixes
stub out McpQueryBar with placeholder box for split PR
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
prototype for stored queries
add mcp-session-id to request
move mcpSessionId to POST body
revert execute_query related changes
update liquibase migration
add tests for drills
layout adjustments
Address review feedback on MCP query-handle store
Schema redesign of mcp_ui_query_handle (renamed mcp_query_handle):
unified UUID PK, indexed mcp_session_id, nullable core_session_id with
cascading FK to core_session. Defines :model/McpQueryHandle deriving
:hook/created-at-timestamped?.
Lifecycle changes:
- store-handle! returns a fresh UUID per call; reads no longer consume
(supports retries and multiple in-flight drills)
- delete! reaps both the core_session and remaining handles by
mcp_session_id; FK cascade handles the rest
- The /ui/drills bypass branch in mcp.api/handler is gone; the iframe
callback now lives in metabase.mcp.callback-api at /api/embed-mcp/drills,
reads Mcp-Session-Id from the header and validates UUID + ownership
Tool dispatch:
- *current-session-id* dynamic var removed; session-id threaded explicitly
through mcp.tools/call-tool
- render_drill_through now takes a {handle uuid} arg; the iframe embeds the
handle in the message so the agent passes it through
Resource registry no longer conjes tools onto a per-URI vector — keyed by
tool name so REPL reloads stay idempotent.
Frontend handler now awaits the handle, embeds it in app.sendMessage, and
falls back to defaultNavigate when MCP plumbing is unavailable or the POST
fails.
Drop dead :uri on registered MCP UI tools
The tool map was being assoc'd with :uri uri, but no caller reads it —
list-tools select-keys'es to [:name :description :inputSchema :_meta] and
drops it before sending to MCP clients, and call-tool only touches :scope
and :response-fn. The URI is already on the registry key and is exposed to
the frontend via :_meta.ui.resourceUri.
Index UI tools by name; one resource per iframe
The previous shape registered a second :render-drill-through resource that
served the exact same iframe — same render-fn, same HTML output. Two URIs
serving identical bytes don't represent two resources.
Collapse back to one resource (the embed-mcp.html iframe) and key tools by
name instead of by URI. Tool names are unique, multiple tools can target the
same iframe via :_meta.ui.resourceUri, and REPL re-registration is still
idempotent because both registry maps overwrite by their key.
Register McpQueryHandle and refresh kondo modules config
Wire the new model into copy/serdes-aware places and refresh the kondo
modules config now that mcp.callback-api is a public API in the mcp
module.
reduce visualization height
exclude McpQueryHandle models from serialization
remove unnecessary Promise.resolve fallback
make drill-thru type stronger
use "Show me the result" instead of "Show me the drill-through result"
harden the prompt for cursor auto model
address kondo lint for Toucan2 table-name defmethods
update schema file to fix type errors
* Show MCP Apps question title without time granularity (#73397)
add minimal question title without time granularity
extract DescribeQueryStageOptions type
add unit test for stripping temporal buckets
fix: preserve non-temporal breakout suffixes when stripping temporal buckets
refine mcp question title generation
* Add QueryExplorerBar pure UI component for MCP Apps (#73373)
add query bar component
revert McpUiAppRoute changes (moved to next branch)
* Apply the query explorer bar to MCP Apps (#73272)
add McpQueryBar with chart type, date filter, and granularity controls
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
update query bar
explore button must open link to question
address code formatting reviews
* Store construct_query result server-side to prevent LLM hallucination (#73210)
Address review feedback on MCP query-handle store
Schema redesign of mcp_ui_query_handle (renamed mcp_query_handle):
unified UUID PK, indexed mcp_session_id, nullable core_session_id with
cascading FK to core_session. Defines :model/McpQueryHandle deriving
:hook/created-at-timestamped?.
Lifecycle changes:
- store-handle! returns a fresh UUID per call; reads no longer consume
(supports retries and multiple in-flight drills)
- delete! reaps both the core_session and remaining handles by
mcp_session_id; FK cascade handles the rest
- The /ui/drills bypass branch in mcp.api/handler is gone; the iframe
callback now lives in metabase.mcp.callback-api at /api/embed-mcp/drills,
reads Mcp-Session-Id from the header and validates UUID + ownership
Tool dispatch:
- *current-session-id* dynamic var removed; session-id threaded explicitly
through mcp.tools/call-tool
- render_drill_through now takes a {handle uuid} arg; the iframe embeds the
handle in the message so the agent passes it through
Resource registry no longer conjes tools onto a per-URI vector — keyed by
tool name so REPL reloads stay idempotent.
Frontend handler now awaits the handle, embeds it in app.sendMessage, and
falls back to defaultNavigate when MCP plumbing is unavailable or the POST
fails.
use stored query results to avoid hallucination
Address review feedback on construct_query handle store
Update construct_query tool description to reflect the new return shape
({"query_handle": "<uuid>"}) so the LLM knows to pass the handle on to
execute_query / visualize_query rather than expect a raw base64 string.
Update execute_query test to use :query_handle now that construct_query
returns it instead of :query.
(Bottom-PR amendments folded into the rebased commit during conflict
resolution: drop dynamic var, switch to :model/McpQueryHandle + read-handle
unified store, log a warning when the agent passes a UUID in :query
instead of :query_handle.)
Fix input schema breaking some mcp clients
Polish visualize_query tool description and error messages
- Drop trailing space from the tool description
- Reword schema comment from "exactly one of" to "at least one of"
(the runtime contract was always at-least-one, not exactly-one)
- Distinguish "neither argument provided" from "handle not found"
so missing-input clients get a clearer error
- Add tests covering the four response branches
* Show authentication and CORS errors for MCP Apps (#73633)
show authentication and CORS errors
update auth error copy to be more actionable
render in ComponentProvider boundary
move into renderContent
* fix: show query bar even when only one data point remains (#73628)
show query bar when one data point remains
* Remove x and y labels from ad-hoc charts for MCP Apps (#73663)
hide x and y axis labels
* Send MCP Apps client header from MCP Apps (#73709)
update metabase client to mcp-apps
* Open drills in Metabase for Claude and tweak tool description (#74087)
* do not perform external drills in claude
* adjust tool call description
* Thumbs up / thumbs down feedback buttons for MCP Apps (#73344)
* Implement feedback buttons
feedback
add explore button for opening in metabase
always show explore on the right
add thumbs up/down button
increase feedback gap
rebase prototype branch
feedback for metabot
add context for feedback
* scope the mcp session handle
* adjust feedback button gap
* add loading state for submit button
* add unit tests for feedback submission
* throw 400 error if feedback fails to submit to harbormaster
* move feedback tests to callback endpoint
* add docstrings for mcp feedback types
* allow submitting multiple feedback
* add docstring for prompt
* code cleanup
* prompt is optional in construct_query for agent api
* add docstring for why prompts has to be stored
* remove active view references
* add timeout to /api/v2/metabot/feedback harbormaster submission
* address kondo linter issues
* Handle MCP feedback submission failures
* prevent race condition on feedback submission
* limit how big construct_query prompt can be
* split tool argument type into input and result
* re-use the type for feedback submission
* cleanup MCP callback tests
---------
Co-authored-by: Anderson <ands.alves.nunes@gmail.com>
Co-authored-by: Timofey Kachalov <timofei@metabase.com>
Co-authored-by: Romeo Van Snick <romeo@romeovansnick.be>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Chris Truter <crisptrutski@users.noreply.github.com>
Co-authored-by: Mihael Konjevic <konjevic@gmail.com>
* Add compression-webpack-plugin
* Enable gzip and brotli compression during builds
* Try serving compressed resources
* Add compressible-resource? helper
* Move check out of handler
* Break out try-compressible-resource
* Use ext-mime-type instead of custom helper
* Use some->
* Use same signature as route/resources
* Remove compressible check
* Fallback to 404
* Add missing import
* Fix lint
* Add compression to embedding sdk too
* Rewrite compression module to es module
* Switch to compression-rspack-plugin
* Pull out env var for compression
* Reuse regex
* Compress svg's too
* Also set content type for uncompressed resources
* Improve naming
* Use destructuring
* Copy compressed ambed assets too
* Ignore .br and .gz files
* Export static-resource handler
* Use static/static-resource handler
* Clean up embedding handlers
* Use get-header
* Update Cypress to get brotli support
* Conditionally load rspack plugin to avoid storybook from choking
* Add log line about asset compression
* Use correct content-encoding header for gzip
* Add support for weak etags
* Remove copySourceMap option which no longer makes sense
* Create output dir if it does not exist
* Make copy plugin use promises
* Move the dot into encoding->extension
* Parse accept-encoding and use identity instead of custom helper
* Add tests for routes.static
* Clarify why the plugin lives in a separate file
* Use more constants from zlib
* Add clarifying comment about :identity
* Do not throw if tmpDir does not exist
* Do not silenly hide errors
* Carry over 304 headers
* Fix tests
* Fix missing import
* Simplify bun.lock
* Use clojure.set/map-invert to create inverted encoding to header map
* Rewrite tests using =?
* Use pos? instead of comparison.
Co-authored-by: metamben <103100869+metamben@users.noreply.github.com>
* Fix test
---------
Co-authored-by: Ryan Laurie <30528226+iethree@users.noreply.github.com>
Co-authored-by: metamben <103100869+metamben@users.noreply.github.com>
* CssVarsDeclarationPlugin: Add plugin and documentation to generate .d.css files at build step
* CssVarsDeclarationPlugin: Add recommended .vscode settings to support CSS vars autocomplete
* CssVarsDeclarationPlugin: Fix nested unions parsing
* CssVarsDeclarationPlugin: Add unit tests
* Update vscode settings for css vars to include Mantine
* Convert `app-embed` to TypeScript
Part of the Accelerate TypeScript Migration project.
Closes DEV-1516
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Use bun in package.json
* Update workflows
* Update more workflows
* Kick ci
* Fix yaml
* Fix type errors
* Compat with snyk
* Fix jest resolutions
* Add another esm package
* Fix aliases and next js missing deps
* Update next js embed tests
* Try fix embed test config
* Fix
* Fix requires in e2e support
* Use bun not yarn in embed bin
* Revert config changes
* Use bun in more scripts and use prepare-release action
* Replace more yarn usages
* Remove overrides from bunfig move to package json
* Revert e2e support changes
* Add back comment
* [ci skip] comment typo
* Update bun lock
* Update to reference bun
* Update to reference bun
* Update license disclaimer
* Tidy tests
* Update to use bun in workflows
* Change aliases
* Update codemirrort selector
* Tidy license generation
* Remove .only
* Fix yarn references
* Checkout .github for release scripts
* Update lockfile
* Re-add package
* update release bunlock
* fix checkout check
---------
Co-authored-by: Ryan Laurie <iethree@gmail.com>
* move the actual sdk folders
* update rspack config and eslint config
* fix relative import in CommonSdkStoryWrapper
* allow default exports in preview.tsx
* update eslint config to allow imports from frontend/src/embedding-sdk-shared
* remove legacy eslint disable directive
* temporarily 'disable' eslint-disable-next-line no-external-references-for-sdk-package-code that has not been ported yet
* update rspack config to use new paths
* update jest config to use new paths
* add `embedding-sdk-package` to restricted imports
* copy eslint files to apply to the new sdk folders
* add eslint-disable-next-line no-restricted-imports to some places where we need emotion
* fix jest setup
* add and use setupEmbeddingSdkEnterprisePlugins
* use `useSetting` instead of `getApplicationColors` to remove enterprise import
* move defineMetabaseAuthConfig to embedding-sdk-shared
* move MetabotProvider to embedding-sdk-bundle
* fix docs generation issue about types
* fix prettier ignore file
* move back tests to ee folder
* remove ../../../ from imports
* fix eslint issues
* fix, again, jest config :sad:
* Convert plugin system to deferred initialization with undo capability
* fixed wrong rebase
* better initialization
* .
* fixed unit tests
* .
* duh
* added back whitelabel overrides for SDK
* fixup
* fixed unit test
* cleanup
* js source of truth for colors
* use more betterer colors
* keyboard shortcut for toggling dark mode
* Adds colorConfig for defining a light and dark color for each color variable
* Copies over dark colors from `dark-mode` branch (excluding variables that don't exist in colorConfig`
* Ports other style changes from `dark-mode` branch
* Revert 3301ed93693
* Ports mantine theme logic from `dark-mode` but uses SSOT colorConfig instead of SEMANTIC_COLOR_SCHEMES
* Fix TS errors
* Fix text color and random white bg on permissions table
* Removing a bunch of usages of JS color... probably breaking things
* Updates mantine color scheme when resolvedColorScheme changes
* a bunch more
* fix progress bars. shame on Nick
* Stubs out forcing light mantine theme when isEmbedding (since it has its own dark mode)
* Fix hard-to-read dark mode straggler caused by one-off bg color
* add orionAlphaInverse colors
* make lighthouse illustration work with CSS vars
* Fixes hover states of query builder header buttons in dark mode
* Updates PivotTables in dark mode to behave similarly to night mode
* Fix upsell CTA hover color in dark mode
* Tweaks admin nav dark mode color
* some small fixes
* Fixes some incorrect brand color values when white-labeling
* Tweaks admin nav bar colors and uses same colors on dark mode as light mode (if it ain't broke...)
* Fix gauge visualization text/input colors in dark mode
* Makes things legible and more consistent in query builder in dark mode
* Fixes a few filter chip stragglers in dark mode
* metabot visits the dark side
* Use ColorSchemeToggle for dashboard night mode button
* Prevents dashboard from using night mode when theme=night is set in the hash
* Update color.ts
* Revert "Prevents dashboard from using night mode when theme=night is set in the hash"
This reverts commit 06a504c088e31c60aca7c7550aa24a0f32edba6c.
* set color scheme for scrollbars
* hard to see toggle in database info
* Embedding and other fixed
* fix blue brand
* Uses canonical dark mode for dashboard night mode and static embedding's dark mode
* Fixes issue where Static Embedding preview pane doesn't show checkerboard background when "Dashboard background" is turned off
* Updates find-never-defined-css-variables.ts so it looks for defined variables in colors.ts. Removes references to now-removed base colors.
* Fixes some TS errors
* happy-ish static viz
* only resolve to color var if name is known
* type corrections, removing auto color scheme
* Passes storybook theme arg to ThemeProvider
* add konami code shortcut for Vamsi
* Fix dashboard context TS errors
* Fix runtime warning
* Prevents whitelabel colors from being used in colors.ts when token lacks whitelabel feature. Updates `filter` and `summarize` colors to use whitelabel value if present.
* re-enable updateColors
* happy types
* Updates storybook renderer to work with stories that set the theme via theme: "dark"
* Fix issue where DatesRangeSdk story doesn't pick up brand color
* green unit tests?
* Reverts unnecessary change carried over from original `dark-mode` POC which changed some loki/storybook backgrounds
* Fix issue where theme switching themes in Question embed previews doesn't appear to do anything
* handfull of e2e suites
* Revives some `theme` infrastructure needed to support `theme=transparent`
* Restores SdkError colors on dark mode (#64306)
* happy unit and e2e tests?
* Fix lint errors
* feat(sdk-bundle): use existing tooltip configuration for dark mode (#64325)
* fix card shadow crash
* backdrop color fix
* Refines ColorSchemeToggle. Color scheme is "auto" by default. When "auto", color scheme is automatically updated when browser/device settings is changed. Switching to the theme that's defined as the browser/device preference will set the color scheme to "auto".
* Adds clarifying "(system preference)" to color scheme toggle tooltip
* embedding e2e, unit tests
* Fix TS error
* update colorConfig for sdkThemeProvider
* force e2e to run in light mode
* Fix embedding-sdk:docs:generate error
* Updates ThemeProvider to ignore from hash if we're outside of static embeds. This prevents old night mode dashboard urls from messing with the new dark mode.
* Fix issue where dark mode shortcut isn't pulling in the latest values (not toggling right)
* Replace hardcoded value with already-defined constant
* fix quotes in css
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
* use firefox compatible scale
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
* fix css quotes
* fix color scheme toggle
* fix test
* fix conflict
* update test
* PR Feedback
* fix embedding homepage flicker
* e2e adjustment
* adding text-hover, fixing checkbox border
* setup.cy green plz
* e2e test for toggling color scheme
* e2e plz
* type check
* e2e adjustment
* Update Loki Snapshots
* test colors in RGB
* OS check for shortcut
---------
Co-authored-by: Ryan Laurie <iethree@gmail.com>
Co-authored-by: Nick Fitzpatrick <nickfitz.582@gmail.com>
Co-authored-by: Brad Anderson <brad@metabase.com>
Co-authored-by: AlessioLaiso <7041012+AlessioLaiso@users.noreply.github.com>
Co-authored-by: Phoomparin Mano <poom@metabase.com>
Co-authored-by: Ryan Laurie <30528226+iethree@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Metabase Automation <github-automation@metabase.com>
* Allow running dev on custom MB_FRONTEND_DEV_PORT
Signed-off-by: Jakub Chodorowicz <jakub@chodorowicz.com>
* Unify port env var naming between JS and Clojure
* Add dev server port info
* Update devenv docs
Co-authored-by: Sébastien <sebastien@metabase.com>
* update docs
---------
Signed-off-by: Jakub Chodorowicz <jakub@chodorowicz.com>
Co-authored-by: Sébastien <sebastien@metabase.com>
* [Admin settings] Show help documentation to connect DB in a side panel
* Add unit tests
* Add more tests / tweaks
* Add e2e tests
* Make sure help content is not rendered if not available
* Self-review tweaks
* Use useDocsUrl in DatabaseHelpSidePanel.tsx
* Use aside element for the side panel
* Use await findBy when possible
* Use JSDoc / Remove unnecessary comment
* Add some style to blockquote
* Add test file for useHelpLink
* Fix failing test
* Add analytics event