@databrainhq/mcp-server 0.3.0-rc.1 → 0.3.0-rc.2

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.
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  createChartAppServer
4
- } from "../chunk-NDVW3ZSJ.js";
5
- import "../chunk-7DS7OLWP.js";
4
+ } from "../chunk-SG7F7PRY.js";
5
+ import "../chunk-3AFT7S6E.js";
6
6
  export {
7
7
  createChartAppServer
8
8
  };
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  loadConfig
4
- } from "../chunk-RF3HTNO7.js";
4
+ } from "../chunk-4OFVDEFU.js";
5
5
  import {
6
6
  createChartAppServer
7
- } from "../chunk-NDVW3ZSJ.js";
8
- import "../chunk-7DS7OLWP.js";
7
+ } from "../chunk-SG7F7PRY.js";
8
+ import "../chunk-3AFT7S6E.js";
9
9
 
10
10
  // src/apps/stdio.ts
11
11
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
@@ -24,7 +24,7 @@ var logger = {
24
24
  // package.json
25
25
  var package_default = {
26
26
  name: "@databrainhq/mcp-server",
27
- version: "0.3.0-rc.1",
27
+ version: "0.3.0-rc.2",
28
28
  description: "MCP server for Databrain embedded analytics - connect databases, create datamarts, configure embeds, and generate frontend code",
29
29
  type: "module",
30
30
  bin: {
@@ -1672,6 +1672,54 @@ var WidgetService = class {
1672
1672
  }
1673
1673
  };
1674
1674
  }
1675
+ /**
1676
+ * Read-only sibling of `ensureTenantDashboardScope`.
1677
+ *
1678
+ * The tenant gate above exists to stop a WRITE landing on the data-app
1679
+ * dashboard when the caller meant a tenant's copy, so it insists the
1680
+ * tenant-scoped embed lookup returns the target. A data-app embed has no
1681
+ * tenant row, `listEmbeds(dataAppName, clientId)` answers with an empty list,
1682
+ * and the render path was denied before it ever reached the backend. That is
1683
+ * the wrong trade for a read: the chart route re-derives everything from the
1684
+ * guest token it is handed (embed inside the token's data app, `allowedEmbeds`,
1685
+ * the tenancy subset for the client, and per-metric client visibility), so the
1686
+ * only thing this check can usefully add is refusing another tenant's embed.
1687
+ */
1688
+ async ensureReadableDashboardScope(params) {
1689
+ const clientId = params.clientId.trim();
1690
+ if (!clientId) {
1691
+ return {
1692
+ ok: false,
1693
+ error: "`clientId` cannot be empty. Pick a tenant/client first."
1694
+ };
1695
+ }
1696
+ let ctx;
1697
+ try {
1698
+ ctx = await this.resolveEmbedContext(params.embedId);
1699
+ } catch (err) {
1700
+ return { ok: false, error: err.message };
1701
+ }
1702
+ if (ctx.embedClientId && ctx.embedClientId !== clientId) {
1703
+ return {
1704
+ ok: false,
1705
+ error: `Embed "${params.embedId}" belongs to another client. Pass the \`clientId\` the embed was created for.`
1706
+ };
1707
+ }
1708
+ if (!ctx.embedClientId && ctx.externalDashboardCreatedBy && ctx.externalDashboardCreatedBy !== clientId) {
1709
+ return {
1710
+ ok: false,
1711
+ error: `Dashboard behind embed "${params.embedId}" belongs to another client. Pass the \`clientId\` the dashboard was created for.`
1712
+ };
1713
+ }
1714
+ return {
1715
+ ok: true,
1716
+ value: {
1717
+ embedId: params.embedId,
1718
+ clientId,
1719
+ dataAppName: ctx.dataAppName || params.dataAppName || null
1720
+ }
1721
+ };
1722
+ }
1675
1723
  /**
1676
1724
  * Resolve a datasource for a widget. Priority:
1677
1725
  * 1. Explicit integrationId + integrationName (fast path).
@@ -1857,6 +1905,7 @@ Do not guess between the two \u2014 wait for the user to choose.`
1857
1905
  dataAppName,
1858
1906
  externalDashboardId,
1859
1907
  dashboardId,
1908
+ embedClientId: isNonEmptyString3(exact.clientId) && exact.clientId || (metadata && isNonEmptyString3(metadata.clientId) ? metadata.clientId : null),
1860
1909
  externalDashboardCreatedBy: (externalDashboard && isNonEmptyString3(externalDashboard.createdBy) ? externalDashboard.createdBy : null) || (isNonEmptyString3(exact.createdBy) ? exact.createdBy : null) || (metadata && isNonEmptyString3(metadata.createdBy) ? metadata.createdBy : null) || (isNonEmptyString3(exact.clientId) ? exact.clientId : null)
1861
1910
  };
1862
1911
  }
@@ -6015,6 +6064,12 @@ function registerGetSemanticLayerGenerationStatus(server, client) {
6015
6064
 
6016
6065
  // src/tools/widgets/list-widgets.ts
6017
6066
  import { z as z29 } from "zod";
6067
+ function widgetReferenceId(widget) {
6068
+ for (const candidate of [widget.externalMetricId, widget.id, widget._id, widget.metricId]) {
6069
+ if (typeof candidate === "string" && candidate.trim().length > 0) return candidate.trim();
6070
+ }
6071
+ return void 0;
6072
+ }
6018
6073
  function registerListWidgets(server, client) {
6019
6074
  const services = createServiceBundle(client);
6020
6075
  const tool = server.tool(
@@ -6043,17 +6098,18 @@ function registerListWidgets(server, client) {
6043
6098
  );
6044
6099
  if (hasChartApps(server)) {
6045
6100
  const visible = (Array.isArray(widgets) ? widgets : []).slice(0, 50);
6046
- return chartResult(`${visible.length} widgets available in the first dashboard page.`, {
6101
+ const references = visible.flatMap((w) => {
6102
+ const widgetId = widgetReferenceId(w);
6103
+ return widgetId ? [{
6104
+ name: typeof w.name === "string" ? w.name.slice(0, 500) : "Untitled widget",
6105
+ reference: { widgetId, embedId, clientId: params.clientId }
6106
+ }] : [];
6107
+ });
6108
+ return chartResult(`${references.length} widgets available in the first dashboard page.`, {
6047
6109
  kind: "dashboard",
6048
6110
  title: "Dashboard",
6049
6111
  rows: [],
6050
- widgets: visible.flatMap((w) => {
6051
- const widgetId = w.externalMetricId || w.id || w._id;
6052
- return typeof widgetId === "string" ? [{
6053
- name: typeof w.name === "string" ? w.name.slice(0, 500) : "Untitled widget",
6054
- reference: { widgetId, embedId, clientId: params.clientId }
6055
- }] : [];
6056
- }),
6112
+ widgets: references,
6057
6113
  description: Array.isArray(widgets) && widgets.length > 50 ? "Showing the first 50 widgets." : ""
6058
6114
  });
6059
6115
  }
@@ -10395,4 +10451,4 @@ export {
10395
10451
  registerAllResources,
10396
10452
  registerAllPrompts
10397
10453
  };
10398
- //# sourceMappingURL=chunk-7DS7OLWP.js.map
10454
+ //# sourceMappingURL=chunk-3AFT7S6E.js.map