diff --git a/frontend/src/metabase-lib/join.ts b/frontend/src/metabase-lib/join.ts
index d25f6bf26cde20d961250b5d9ea23cd7a2104a12..f7913c36a681291408ced8055c40bd41ac4533e9 100644
--- a/frontend/src/metabase-lib/join.ts
+++ b/frontend/src/metabase-lib/join.ts
@@ -115,3 +115,18 @@ export function removeJoin(
 ): Query {
   return ML.remove_join(query, stageIndex, joinSpec);
 }
+
+export function joinedThing(query: Query, join: Join): Joinable {
+  return ML.joined_thing(query, join);
+}
+
+export type PickerInfo = {
+  databaseId: number;
+  tableId: number;
+  cardId?: number;
+  isModel?: boolean;
+};
+
+export function pickerInfo(query: Query, metadata: Joinable): PickerInfo {
+  return ML.picker_info(query, metadata);
+}
diff --git a/src/metabase/lib/join.cljc b/src/metabase/lib/join.cljc
index dfb83f924b7fdb363950d0818c8e0fc72c76526c..5d2d3ee81482e53fa197cff4100a4a3815eef47e 100644
--- a/src/metabase/lib/join.cljc
+++ b/src/metabase/lib/join.cljc
@@ -579,3 +579,12 @@
    (when-let [pk-col (pk-column query stage-number joinable)]
      (when-let [fk-col (fk-column-for query stage-number pk-col)]
        (lib.filter/filter-clause (equals-join-condition-operator-definition) fk-col pk-col)))))
+
+(mu/defn joined-thing :- [:maybe [:or lib.metadata/TableMetadata lib.metadata/CardMetadata]]
+  "Return metadata about the origin of `a-join` using `metadata-providerable` as the source of information."
+  [metadata-providerable :- lib.metadata/MetadataProviderable
+   a-join                :- ::lib.schema.join/join]
+  (let [origin (-> a-join :stages first)]
+    (cond
+      (:source-card origin)  (lib.metadata/card metadata-providerable (:source-card origin))
+      (:source-table origin) (lib.metadata/table metadata-providerable (:source-table origin)))))
diff --git a/src/metabase/lib/js.cljs b/src/metabase/lib/js.cljs
index 3f0e2912c7b15016ea67b41ba22db7bb97cdfef5..1d118ec3d8a5c4e6c184919471d2e4b4d1e99055 100644
--- a/src/metabase/lib/js.cljs
+++ b/src/metabase/lib/js.cljs
@@ -11,6 +11,7 @@
    [medley.core :as m]
    [metabase.lib.convert :as convert]
    [metabase.lib.core :as lib.core]
+   [metabase.lib.join :as lib.join]
    [metabase.lib.js.metadata :as js.metadata]
    [metabase.lib.metadata.protocols :as lib.metadata.protocols]
    [metabase.lib.stage :as lib.stage]
@@ -520,6 +521,25 @@
   [a-query stage-number join-spec]
   (lib.core/remove-join a-query stage-number join-spec))
 
+(defn ^:export joined-thing
+  "Return metadata about the origin of `join` using `metadata-providerable` as the source of information."
+  [a-query a-join]
+  (lib.join/joined-thing a-query a-join))
+
+(defn ^:export picker-info
+  "Temporary solution providing access to internal IDs for the FE to pass on to MLv1 functions."
+  [a-query metadata]
+  (case (:lib/type metadata)
+    :metadata/table #js {:databaseId (:database a-query)
+                         :tableId (:id metadata)}
+    :metadata/card  #js {:databaseId (:database a-query)
+                         :tableId (str "card__" (:id metadata))
+                         :cardId (:id metadata)
+                         :isModel (:dataset metadata)}
+    (do
+      (log/warn "Cannot provide picker-info for" (:lib/type metadata))
+      nil)))
+
 (defn ^:export external-op
   "Convert the internal operator `clause` to the external format."
   [clause]
diff --git a/src/metabase/lib/js/metadata.cljs b/src/metabase/lib/js/metadata.cljs
index 3207e2e27595ab46d85b86a4dbd6f803cbdb379d..98fe12d3271afa9b8b1c6f328e662bcb36a02dae 100644
--- a/src/metabase/lib/js/metadata.cljs
+++ b/src/metabase/lib/js/metadata.cljs
@@ -253,6 +253,7 @@
       :fields          (parse-fields v)
       :visibility-type (keyword v)
       :dataset-query   (js->clj v :keywordize-keys true)
+      :dataset         v
       ;; this is not complete, add more stuff as needed.
       v)))
 
@@ -263,7 +264,7 @@
   (or (object-get obj "_card")
       obj))
 
-(defn- assamble-card
+(defn- assemble-card
   [metadata id]
   (let [parse-card-ignoring-plain-object (parse-object-fn :card {:use-plain-object? false})
         parse-card (parse-object-fn :card)]
@@ -288,7 +289,7 @@
   [_object-type metadata]
   (into {}
         (map (fn [id]
-               [id (delay (assamble-card metadata id))]))
+               [id (delay (assemble-card metadata id))]))
         (-> #{}
             (into (keep lib.util/legacy-string-table-id->card-id)
                   (gobject/getKeys (object-get metadata "tables")))
diff --git a/src/metabase/lib/metadata.cljc b/src/metabase/lib/metadata.cljc
index 8c894a96021b89cd562c9636ae27138618e3a3fa..53bf70a6b3a764b4be1e1b04733387367aa16058 100644
--- a/src/metabase/lib/metadata.cljc
+++ b/src/metabase/lib/metadata.cljc
@@ -115,7 +115,8 @@
    [:dataset-query   {:optional true} :map]
    ;; vector of column metadata maps; these are ALMOST the correct shape to be [[ColumnMetadata]], but they're
    ;; probably missing `:lib/type` and probably using `:snake_case` keys.
-   [:result-metadata {:optional true} [:maybe [:sequential :map]]]])
+   [:result-metadata {:optional true} [:maybe [:sequential :map]]]
+   [:dataset {:optional true} :boolean]])
 
 (def SegmentMetadata
   "More or less the same as a [[metabase.models.segment]], but with kebab-case keys."