@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.
- package/dist/apps/server.js +2 -2
- package/dist/apps/stdio.js +3 -3
- package/dist/{chunk-7DS7OLWP.js → chunk-3AFT7S6E.js} +66 -10
- package/dist/chunk-3AFT7S6E.js.map +1 -0
- package/dist/{chunk-RF3HTNO7.js → chunk-4OFVDEFU.js} +2 -2
- package/dist/{chunk-JCXUZ3QZ.js → chunk-CX3CS62P.js} +1 -1
- package/dist/chunk-CX3CS62P.js.map +1 -0
- package/dist/{chunk-NDVW3ZSJ.js → chunk-SG7F7PRY.js} +7 -3
- package/dist/chunk-SG7F7PRY.js.map +1 -0
- package/dist/index.js +3 -3
- package/dist/{main-7QNRH6X4.js → main-RYW6PTR4.js} +14 -7
- package/dist/main-RYW6PTR4.js.map +1 -0
- package/dist/{test-only-EJ5O4WN5.js → test-only-B4EVUNFU.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-7DS7OLWP.js.map +0 -1
- package/dist/chunk-JCXUZ3QZ.js.map +0 -1
- package/dist/chunk-NDVW3ZSJ.js.map +0 -1
- package/dist/main-7QNRH6X4.js.map +0 -1
- /package/dist/{chunk-RF3HTNO7.js.map → chunk-4OFVDEFU.js.map} +0 -0
- /package/dist/{test-only-EJ5O4WN5.js.map → test-only-B4EVUNFU.js.map} +0 -0
package/dist/apps/server.js
CHANGED
package/dist/apps/stdio.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
loadConfig
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-4OFVDEFU.js";
|
|
5
5
|
import {
|
|
6
6
|
createChartAppServer
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
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.
|
|
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
|
-
|
|
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:
|
|
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-
|
|
10454
|
+
//# sourceMappingURL=chunk-3AFT7S6E.js.map
|