@databrainhq/mcp-server 0.3.0-rc.12 → 0.3.0-rc.14

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 (46) hide show
  1. package/.mcp.json +6 -1
  2. package/dist/apps/server.d.ts +102 -389
  3. package/dist/apps/server.js +5 -5
  4. package/dist/apps/stdio.d.ts +1 -2
  5. package/dist/apps/stdio.js +6 -6
  6. package/dist/{bundle-TDQXWIPM.js → bundle-QJNCUMNY.js} +2 -2
  7. package/dist/{chunk-Q5EYDKSA.js → chunk-2F7V6RZR.js} +511 -107
  8. package/dist/chunk-2F7V6RZR.js.map +1 -0
  9. package/dist/{chunk-347U6GXR.js → chunk-AWICHHDU.js} +153 -61
  10. package/dist/chunk-AWICHHDU.js.map +1 -0
  11. package/dist/{chunk-Z3ZHN4UW.js → chunk-CEGHG5U3.js} +59 -18
  12. package/dist/chunk-CEGHG5U3.js.map +1 -0
  13. package/dist/{chunk-ZTHGF27R.js → chunk-NIC5MAGC.js} +317 -147
  14. package/dist/chunk-NIC5MAGC.js.map +1 -0
  15. package/dist/{chunk-V3UW3B6U.js → chunk-S65KA3Z7.js} +26 -11
  16. package/dist/chunk-S65KA3Z7.js.map +1 -0
  17. package/dist/{chunk-OLOC2MTA.js → chunk-UYFFFAYV.js} +11722 -10560
  18. package/dist/chunk-UYFFFAYV.js.map +1 -0
  19. package/dist/{chunk-LACJHQYH.js → chunk-VQ5G5AZV.js} +10 -7
  20. package/dist/chunk-VQ5G5AZV.js.map +1 -0
  21. package/dist/cli.d.ts +16 -15
  22. package/dist/cli.js +134 -36
  23. package/dist/cli.js.map +1 -1
  24. package/dist/custom-chart/custom-runtime.js +6 -6
  25. package/dist/custom-chart/template/chart.ts +116 -28
  26. package/dist/custom-chart/template/icon.svg +1 -1
  27. package/dist/custom-chart/template/manifest.json +66 -12
  28. package/dist/custom-chart/template/sample-data.json +21 -3
  29. package/dist/index.d.ts +1 -2
  30. package/dist/index.js +20 -10
  31. package/dist/index.js.map +1 -1
  32. package/dist/{main-IUV24DMP.js → main-QCBVJSSR.js} +363 -155
  33. package/dist/main-QCBVJSSR.js.map +1 -0
  34. package/dist/{test-only-K7QTSVO4.js → test-only-6474NMTR.js} +12 -8
  35. package/dist/test-only-6474NMTR.js.map +1 -0
  36. package/package.json +20 -9
  37. package/dist/chunk-347U6GXR.js.map +0 -1
  38. package/dist/chunk-LACJHQYH.js.map +0 -1
  39. package/dist/chunk-OLOC2MTA.js.map +0 -1
  40. package/dist/chunk-Q5EYDKSA.js.map +0 -1
  41. package/dist/chunk-V3UW3B6U.js.map +0 -1
  42. package/dist/chunk-Z3ZHN4UW.js.map +0 -1
  43. package/dist/chunk-ZTHGF27R.js.map +0 -1
  44. package/dist/main-IUV24DMP.js.map +0 -1
  45. package/dist/test-only-K7QTSVO4.js.map +0 -1
  46. /package/dist/{bundle-TDQXWIPM.js.map → bundle-QJNCUMNY.js.map} +0 -0
@@ -22,8 +22,8 @@ var HostedAuthError = class extends Error {
22
22
 
23
23
  // src/hosted/auth.ts
24
24
  import { createHash, timingSafeEqual } from "crypto";
25
- import { open } from "fs/promises";
26
25
  import { constants } from "fs";
26
+ import { open } from "fs/promises";
27
27
  import { z } from "zod";
28
28
  var identity = z.string().min(1).max(512).regex(/^[^\x00-\x1f\x7f]+$/);
29
29
  var workspaceSchema = z.object({ id: identity, name: identity.optional() }).strip();
@@ -36,7 +36,10 @@ var principalSchema = z.object({
36
36
  workspaceName: identity.optional(),
37
37
  workspaces: z.union([
38
38
  z.object({ mode: z.literal("all") }).strip(),
39
- z.object({ mode: z.literal("list"), ids: z.array(identity).min(1).max(100) }).strip()
39
+ z.object({
40
+ mode: z.literal("list"),
41
+ ids: z.array(identity).min(1).max(100)
42
+ }).strip()
40
43
  ]).optional(),
41
44
  grantedWorkspaces: z.array(workspaceSchema).max(1e3).optional(),
42
45
  // The issuer's own pick; recomputed below from grantedWorkspaces, never trusted on its own.
@@ -48,8 +51,16 @@ var principalSchema = z.object({
48
51
  tenantIds: z.array(identity).optional()
49
52
  }).strict();
50
53
  function normalizeWorkspaces(value) {
51
- const { defaultWorkspace: _default, workspaceId, workspaceName, grantedWorkspaces, ...rest } = value;
52
- const granted = grantedWorkspaces ?? (workspaceId ? [workspaceName === void 0 ? { id: workspaceId } : { id: workspaceId, name: workspaceName }] : []);
54
+ const {
55
+ defaultWorkspace: _default,
56
+ workspaceId,
57
+ workspaceName,
58
+ grantedWorkspaces,
59
+ ...rest
60
+ } = value;
61
+ const granted = grantedWorkspaces ?? (workspaceId ? [
62
+ workspaceName === void 0 ? { id: workspaceId } : { id: workspaceId, name: workspaceName }
63
+ ] : []);
53
64
  if (!granted.length || new Set(granted.map((item) => item.id)).size !== granted.length || workspaceId !== void 0 && !granted.some((item) => item.id === workspaceId)) {
54
65
  throw new HostedAuthError(401, "invalid_token");
55
66
  }
@@ -74,12 +85,21 @@ var FilePatStore = class {
74
85
  this.path = path;
75
86
  }
76
87
  async findByHash(hash) {
77
- const handle = await open(this.path, constants.O_RDONLY | constants.O_NOFOLLOW);
88
+ const handle = await open(
89
+ this.path,
90
+ constants.O_RDONLY | constants.O_NOFOLLOW
91
+ );
78
92
  try {
79
93
  const stat = await handle.stat();
80
- if (!stat.isFile() || (stat.mode & 63) !== 0 || stat.size > 1048576 || process.getuid && stat.uid !== process.getuid()) throw new Error("Invalid credential store");
94
+ if (!stat.isFile() || (stat.mode & 63) !== 0 || stat.size > 1048576 || process.getuid && stat.uid !== process.getuid())
95
+ throw new Error("Invalid credential store");
81
96
  const records = z.array(recordSchema).max(1e3).parse(JSON.parse(await handle.readFile("utf8")));
82
- const matches = records.filter((record) => timingSafeEqual(Buffer.from(record.hash, "hex"), Buffer.from(hash, "hex")));
97
+ const matches = records.filter(
98
+ (record) => timingSafeEqual(
99
+ Buffer.from(record.hash, "hex"),
100
+ Buffer.from(hash, "hex")
101
+ )
102
+ );
83
103
  if (matches.length > 1) throw new Error("Ambiguous credential store");
84
104
  return matches[0];
85
105
  } finally {
@@ -89,28 +109,49 @@ var FilePatStore = class {
89
109
  };
90
110
  function validatePrincipal(value, resource, kind) {
91
111
  const parsed = principalSchema.safeParse(value);
92
- if (!parsed.success || parsed.data.resource !== resource || parsed.data.credentialType !== kind || parsed.data.expiresAt !== void 0 && parsed.data.expiresAt <= Date.now() / 1e3 || kind === "pat" && parsed.success && parsed.data.expiresAt === void 0) throw new HostedAuthError(401, "invalid_token");
112
+ if (!parsed.success || parsed.data.resource !== resource || parsed.data.credentialType !== kind || parsed.data.expiresAt !== void 0 && parsed.data.expiresAt <= Date.now() / 1e3 || kind === "pat" && parsed.success && parsed.data.expiresAt === void 0)
113
+ throw new HostedAuthError(401, "invalid_token");
93
114
  return normalizeWorkspaces(parsed.data);
94
115
  }
95
116
  function createBearerVerifier(adapter, resource, pats) {
96
117
  return async (token) => {
97
118
  try {
98
- if (!/^[A-Za-z0-9._~+\/-]+=*$/.test(token) || token.length > 8192) throw new HostedAuthError(401, "invalid_token");
119
+ if (!/^[A-Za-z0-9._~+/-]+=*$/.test(token) || token.length > 8192)
120
+ throw new HostedAuthError(401, "invalid_token");
99
121
  if (!token.startsWith("dbp_")) {
100
- return validatePrincipal(await adapter.verifyOAuth(token, resource), resource, "oauth");
122
+ return validatePrincipal(
123
+ await adapter.verifyOAuth(token, resource),
124
+ resource,
125
+ "oauth"
126
+ );
101
127
  }
102
- if (!/^dbp_[A-Za-z0-9_-]{32,}$/.test(token)) throw new HostedAuthError(401, "invalid_token");
128
+ if (!/^dbp_[A-Za-z0-9_-]{32,}$/.test(token))
129
+ throw new HostedAuthError(401, "invalid_token");
103
130
  const record = await pats?.findByHash(hashCredential(token));
104
- if (!record || record.revokedAt !== null || record.hash !== hashCredential(token)) throw new HostedAuthError(401, "invalid_token");
131
+ if (!record || record.revokedAt !== null || record.hash !== hashCredential(token))
132
+ throw new HostedAuthError(401, "invalid_token");
105
133
  const stored = validatePrincipal(record.principal, resource, "pat");
106
- const resolved = validatePrincipal(await adapter.resolvePatGrant(structuredClone(stored)), resource, "pat");
107
- for (const key of ["userId", "companyId", "clientId", "resource"]) {
108
- if (resolved[key] !== stored[key]) throw new HostedAuthError(401, "invalid_token");
134
+ const resolved = validatePrincipal(
135
+ await adapter.resolvePatGrant(structuredClone(stored)),
136
+ resource,
137
+ "pat"
138
+ );
139
+ for (const key of [
140
+ "userId",
141
+ "companyId",
142
+ "clientId",
143
+ "resource"
144
+ ]) {
145
+ if (resolved[key] !== stored[key])
146
+ throw new HostedAuthError(401, "invalid_token");
109
147
  }
110
- if (resolved.grantedWorkspaces.some((item) => !stored.grantedWorkspaces.some((old) => old.id === item.id))) {
148
+ if (resolved.grantedWorkspaces.some(
149
+ (item) => !stored.grantedWorkspaces.some((old) => old.id === item.id)
150
+ )) {
111
151
  throw new HostedAuthError(401, "invalid_token");
112
152
  }
113
- if (resolved.expiresAt > stored.expiresAt || resolved.scopes.some((scope) => !stored.scopes.includes(scope)) || resolved.tenantIds?.some((id) => !stored.tenantIds?.includes(id))) throw new HostedAuthError(401, "invalid_token");
153
+ if (resolved.expiresAt > stored.expiresAt || resolved.scopes.some((scope) => !stored.scopes.includes(scope)) || resolved.tenantIds?.some((id) => !stored.tenantIds?.includes(id)))
154
+ throw new HostedAuthError(401, "invalid_token");
114
155
  return resolved;
115
156
  } catch (error) {
116
157
  if (error instanceof HostedAuthError) throw error;
@@ -127,4 +168,4 @@ export {
127
168
  FilePatStore,
128
169
  createBearerVerifier
129
170
  };
130
- //# sourceMappingURL=chunk-Z3ZHN4UW.js.map
171
+ //# sourceMappingURL=chunk-CEGHG5U3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hosted/types.ts","../src/hosted/auth.ts"],"sourcesContent":["import type { RequestOptions } from '../client/types.js';\n\nexport const HOSTED_SCOPES = [\n 'mcp:dashboards:read',\n 'mcp:dashboards:write',\n 'mcp:datamarts:read',\n 'mcp:datamarts:write',\n 'mcp:embeds:write',\n 'mcp:query',\n 'mcp:custom-charts:read',\n 'mcp:custom-charts:write',\n] as const;\nexport type HostedScope = (typeof HOSTED_SCOPES)[number];\n\n/** A workspace this sign-in may act in, as the issuer resolved it for this request. */\nexport interface GrantedWorkspace {\n id: string;\n name?: string;\n}\n\n/** What the user approved at consent: a list of workspaces, or every workspace they can access. */\nexport type GrantWorkspaces = { mode: 'all' } | { mode: 'list'; ids: string[] };\n\n/** Only the trusted auth adapter may produce this context. Never populate it from MCP input. */\nexport interface HostedPrincipal {\n actorKind: 'user';\n credentialType: 'oauth' | 'pat';\n userId: string;\n companyId: string;\n /** Set only when exactly one workspace is granted: the default for every call. */\n workspaceId?: string;\n workspaceName?: string;\n /** The grant as approved. Absent from issuers that grant one workspace only. */\n workspaces?: GrantWorkspaces;\n /**\n * Live: the granted workspaces the user can still access, read on every request.\n * Absent only on a principal built before multi-workspace grants (then `workspaceId`).\n */\n grantedWorkspaces?: GrantedWorkspace[];\n /** OAuth application ID, NOT the tenant identifier called clientId by legacy tools. */\n clientId: string;\n resource: string;\n scopes: HostedScope[];\n /** Required for stored PATs. OAuth may delegate expiry to fresh provider validation. */\n expiresAt?: number;\n /** Explicit tenant allow-list resolved by the backend; absent means no tenant access. */\n tenantIds?: string[];\n}\n\nexport interface PatRecord {\n hash: string;\n revokedAt: number | null;\n principal: HostedPrincipal;\n}\n\nexport interface PatStore {\n findByHash(hash: string): Promise<PatRecord | undefined>;\n}\n\n/**\n * Opaque per-request handle from `HostedAdapter.delegate`. It carries nothing a tool,\n * log or serializer can read; only the adapter that made it can act with it.\n */\nexport interface HostedDelegation {\n readonly kind: 'hosted-delegation';\n}\n\n/** Production integration must recheck membership, policy and revocation on every call. */\nexport interface HostedAdapter {\n verifyOAuth(token: string, resource: string): Promise<HostedPrincipal>;\n resolvePatGrant(principal: HostedPrincipal): Promise<HostedPrincipal>;\n /**\n * Optional. Bind this request's verified OAuth bearer to an opaque handle, so\n * executeRequest can act as this user at the configured issuer, which re-verifies\n * the token and enforces workspace, object and role checks on every call.\n */\n delegate?(token: string, principal: HostedPrincipal): HostedDelegation;\n /**\n * Execute as this user/workspace with backend resource and tenant checks and auditing.\n * Receives NO incoming bearer or server service credential: only the opaque handle.\n * Do not impersonate a static service token.\n * Return the raw API result: the shared client performs its usual data unwrapping.\n * `workspace` is the granted workspace this tool call acts in, when one is known; the\n * adapter names it to the issuer and nowhere else.\n */\n executeRequest(\n options: RequestOptions,\n principal: HostedPrincipal,\n delegation?: HostedDelegation,\n workspace?: GrantedWorkspace\n ): Promise<unknown>;\n}\n\nexport interface HostedConfig {\n publicUrl: string;\n issuer: string;\n /** Where the issuer's API is reached, when not at the issuer origin itself. */\n apiUrl?: string;\n port: number;\n bind: string;\n testOnly: boolean;\n}\n\n/** The backend's own status, code and message for a 4xx that is not an auth denial. */\nexport interface HostedErrorDetail {\n status: number;\n code?: string;\n message?: string;\n}\n\nexport class HostedAuthError extends Error {\n constructor(\n public readonly status: 400 | 401 | 403 | 404 | 503,\n public readonly code: string,\n public readonly detail?: HostedErrorDetail\n ) {\n super(code);\n }\n}\n","import { createHash, timingSafeEqual } from 'node:crypto';\nimport { constants } from 'node:fs';\nimport { open } from 'node:fs/promises';\nimport { z } from 'zod';\nimport type {\n HostedAdapter,\n HostedPrincipal,\n PatRecord,\n PatStore,\n} from './types.js';\nimport { HOSTED_SCOPES, HostedAuthError } from './types.js';\n\nconst identity = z\n .string()\n .min(1)\n .max(512)\n // biome-ignore lint/suspicious/noControlCharactersInRegex: Identity validation intentionally rejects control characters.\n .regex(/^[^\\x00-\\x1f\\x7f]+$/);\nconst workspaceSchema = z\n .object({ id: identity, name: identity.optional() })\n .strip();\nexport const principalSchema = z\n .object({\n actorKind: z.literal('user'),\n credentialType: z.enum(['oauth', 'pat']),\n userId: identity,\n companyId: identity,\n workspaceId: identity.optional(),\n workspaceName: identity.optional(),\n workspaces: z\n .union([\n z.object({ mode: z.literal('all') }).strip(),\n z\n .object({\n mode: z.literal('list'),\n ids: z.array(identity).min(1).max(100),\n })\n .strip(),\n ])\n .optional(),\n grantedWorkspaces: z.array(workspaceSchema).max(1000).optional(),\n // The issuer's own pick; recomputed below from grantedWorkspaces, never trusted on its own.\n defaultWorkspace: workspaceSchema.optional(),\n clientId: identity,\n resource: z.string().url(),\n scopes: z.array(z.enum(HOSTED_SCOPES)),\n expiresAt: z.number().finite().positive().optional(),\n tenantIds: z.array(identity).optional(),\n })\n .strict();\n\n/**\n * One shape for every issuer: the live granted list, and `workspaceId`/`workspaceName`\n * only when exactly one workspace is granted (the default for each call). An issuer\n * that grants one workspace sends only `workspaceId`; read that as a one-item list.\n * No workspace left, duplicate ids, or a `workspaceId` outside the list is refused.\n */\nfunction normalizeWorkspaces(\n value: z.infer<typeof principalSchema>\n): HostedPrincipal {\n const {\n defaultWorkspace: _default,\n workspaceId,\n workspaceName,\n grantedWorkspaces,\n ...rest\n } = value;\n const granted =\n grantedWorkspaces ??\n (workspaceId\n ? [\n workspaceName === undefined\n ? { id: workspaceId }\n : { id: workspaceId, name: workspaceName },\n ]\n : []);\n if (\n !granted.length ||\n new Set(granted.map((item) => item.id)).size !== granted.length ||\n (workspaceId !== undefined &&\n !granted.some((item) => item.id === workspaceId))\n ) {\n throw new HostedAuthError(401, 'invalid_token');\n }\n const only = granted.length === 1 ? granted[0] : undefined;\n return {\n ...rest,\n grantedWorkspaces: granted,\n ...(only ? { workspaceId: only.id } : {}),\n ...(only?.name !== undefined ? { workspaceName: only.name } : {}),\n };\n}\nconst recordSchema = z\n .object({\n hash: z.string().regex(/^[a-f0-9]{64}$/),\n revokedAt: z.number().finite().nullable(),\n principal: principalSchema,\n })\n .strict();\n\nexport function hashCredential(token: string): string {\n return createHash('sha256').update(token).digest('hex');\n}\n\n/** Reread on every request: an atomic file replacement revokes immediately, without restart. */\nexport class FilePatStore implements PatStore {\n constructor(private readonly path: string) {}\n async findByHash(hash: string): Promise<PatRecord | undefined> {\n const handle = await open(\n this.path,\n constants.O_RDONLY | constants.O_NOFOLLOW\n );\n try {\n const stat = await handle.stat();\n if (\n !stat.isFile() ||\n (stat.mode & 0o077) !== 0 ||\n stat.size > 1_048_576 ||\n (process.getuid && stat.uid !== process.getuid())\n )\n throw new Error('Invalid credential store');\n const records = z\n .array(recordSchema)\n .max(1000)\n .parse(JSON.parse(await handle.readFile('utf8')));\n const matches = records.filter((record) =>\n timingSafeEqual(\n Buffer.from(record.hash, 'hex'),\n Buffer.from(hash, 'hex')\n )\n );\n // Duplicate records are ambiguous, including an active/revoked pair.\n if (matches.length > 1) throw new Error('Ambiguous credential store');\n return matches[0];\n } finally {\n await handle.close();\n }\n }\n}\n\nfunction validatePrincipal(\n value: unknown,\n resource: string,\n kind: 'oauth' | 'pat'\n): HostedPrincipal {\n const parsed = principalSchema.safeParse(value);\n if (\n !parsed.success ||\n parsed.data.resource !== resource ||\n parsed.data.credentialType !== kind ||\n (parsed.data.expiresAt !== undefined &&\n parsed.data.expiresAt <= Date.now() / 1000) ||\n (kind === 'pat' && parsed.success && parsed.data.expiresAt === undefined)\n )\n throw new HostedAuthError(401, 'invalid_token');\n return normalizeWorkspaces(parsed.data);\n}\n\nexport function createBearerVerifier(\n adapter: HostedAdapter,\n resource: string,\n pats?: PatStore\n) {\n return async (token: string): Promise<HostedPrincipal> => {\n try {\n if (!/^[A-Za-z0-9._~+/-]+=*$/.test(token) || token.length > 8192)\n throw new HostedAuthError(401, 'invalid_token');\n if (!token.startsWith('dbp_')) {\n return validatePrincipal(\n await adapter.verifyOAuth(token, resource),\n resource,\n 'oauth'\n );\n }\n if (!/^dbp_[A-Za-z0-9_-]{32,}$/.test(token))\n throw new HostedAuthError(401, 'invalid_token');\n const record = await pats?.findByHash(hashCredential(token));\n if (\n !record ||\n record.revokedAt !== null ||\n record.hash !== hashCredential(token)\n )\n throw new HostedAuthError(401, 'invalid_token');\n const stored = validatePrincipal(record.principal, resource, 'pat');\n const resolved = validatePrincipal(\n await adapter.resolvePatGrant(structuredClone(stored)),\n resource,\n 'pat'\n );\n // Membership resolution may narrow a stored grant, never move or expand it.\n for (const key of [\n 'userId',\n 'companyId',\n 'clientId',\n 'resource',\n ] as const) {\n if (resolved[key] !== stored[key])\n throw new HostedAuthError(401, 'invalid_token');\n }\n if (\n resolved.grantedWorkspaces!.some(\n (item) => !stored.grantedWorkspaces!.some((old) => old.id === item.id)\n )\n ) {\n throw new HostedAuthError(401, 'invalid_token');\n }\n if (\n resolved.expiresAt! > stored.expiresAt! ||\n resolved.scopes.some((scope) => !stored.scopes.includes(scope)) ||\n resolved.tenantIds?.some((id) => !stored.tenantIds?.includes(id))\n )\n throw new HostedAuthError(401, 'invalid_token');\n return resolved;\n } catch (error) {\n if (error instanceof HostedAuthError) throw error;\n // No raw verifier, filesystem or remote errors can disclose credential values.\n throw new HostedAuthError(401, 'invalid_token');\n }\n };\n}\n"],"mappings":"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","names":[]}