@databrainhq/mcp-server 0.1.0
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/README.md +283 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5249 -0
- package/dist/index.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/utils/config.ts","../src/server.ts","../src/utils/cache.ts","../src/utils/errors.ts","../src/utils/logger.ts","../src/client/databrain-client.ts","../src/tools/infrastructure/list-datasources.ts","../src/tools/data-app/create-data-app.ts","../src/tools/data-app/list-data-apps.ts","../src/tools/data-app/create-api-token.ts","../src/tools/data-app/list-api-tokens.ts","../src/tools/data-app/rotate-api-token.ts","../src/tools/datamart/list-datamarts.ts","../src/tools/datamart/get-semantic-layer-status.ts","../src/tools/embed/create-embed.ts","../src/tools/embed/list-embeds.ts","../src/tools/embed/get-embed-details.ts","../src/tools/embed/update-embed.ts","../src/tools/embed/delete-embed.ts","../src/tools/embed/rename-embed.ts","../src/tools/embed/apply-theme-preset.ts","../src/tools/frontend/generate-guest-token.ts","../src/tools/frontend/generate-embed-code.ts","../src/templates/react.ts","../src/templates/nextjs.ts","../src/templates/vue.ts","../src/templates/angular.ts","../src/templates/svelte.ts","../src/templates/solidjs.ts","../src/templates/vanilla.ts","../src/templates/index.ts","../src/tools/analytics/list-dashboards.ts","../src/tools/analytics/list-metrics.ts","../src/tools/analytics/query-metric-data.ts","../src/tools/analytics/get-dashboard-data.ts","../src/tools/analytics/ask-ai-pilot.ts","../src/tools/analytics/download-metric-csv.ts","../src/tools/analytics/list-scheduled-reports.ts","../src/tools/analytics/export-dashboard.ts","../src/tools/analytics/import-dashboard.ts","../src/tools/orchestration/setup-embed-interactive.ts","../src/tools/registry.ts","../src/resources/content/getting-started.ts","../src/resources/content/api-reference.ts","../src/resources/content/embedding-guide.ts","../src/resources/content/filter-reference.ts","../src/resources/content/theme-reference.ts","../src/resources/content/web-component-reference.ts","../src/resources/content/self-serve-reference.ts","../src/resources/content/semantic-layer-guide.ts","../src/resources/content/multi-tenancy-guide.ts","../src/resources/registry.ts","../src/prompts/explore-data.ts","../src/prompts/registry.ts"],"sourcesContent":["import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { loadConfig } from './utils/config.js';\nimport { createServer } from './server.js';\nimport { logger } from './utils/logger.js';\n\nasync function main(): Promise<void> {\n try {\n const config = loadConfig();\n const server = createServer(config);\n const transport = new StdioServerTransport();\n\n logger.info('Starting Databrain MCP server...');\n await server.connect(transport);\n logger.info('Databrain MCP server connected via stdio');\n } catch (error) {\n logger.error('Failed to start server', error);\n process.exit(1);\n }\n}\n\nmain();\n","import { z } from 'zod';\n\nconst configSchema = z\n .object({\n serviceToken: z.string().min(1).optional(),\n apiToken: z.string().min(1).optional(),\n apiUrl: z.string().url().default('https://api.usedatabrain.com'),\n })\n .refine((c) => c.serviceToken || c.apiToken, {\n message:\n 'At least one of DATABRAIN_SERVICE_TOKEN or DATABRAIN_API_TOKEN must be set',\n });\n\nexport type Config = z.infer<typeof configSchema>;\n\nexport function loadConfig(): Config {\n return configSchema.parse({\n serviceToken: process.env.DATABRAIN_SERVICE_TOKEN || undefined,\n apiToken: process.env.DATABRAIN_API_TOKEN || undefined,\n apiUrl:\n process.env.DATABRAIN_API_URL || 'https://api.usedatabrain.com',\n });\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { DatabrainClient } from './client/databrain-client.js';\nimport type { Config } from './utils/config.js';\nimport { registerAllTools } from './tools/registry.js';\nimport { registerAllResources } from './resources/registry.js';\nimport { registerAllPrompts } from './prompts/registry.js';\n\nexport function createServer(config: Config): McpServer {\n const server = new McpServer({\n name: 'databrain',\n version: '0.1.0',\n description:\n 'Databrain MCP Server — connect databases, create datamarts, configure embeds, and generate frontend code for embedded analytics',\n });\n\n const client = new DatabrainClient(config);\n\n registerAllTools(server, client);\n registerAllResources(server);\n registerAllPrompts(server);\n\n return server;\n}\n","interface CacheEntry<T> {\n value: T;\n expiresAt: number;\n}\n\nexport class TtlCache {\n private store = new Map<string, CacheEntry<unknown>>();\n\n get<T>(key: string): T | undefined {\n const entry = this.store.get(key);\n if (!entry) return undefined;\n if (Date.now() > entry.expiresAt) {\n this.store.delete(key);\n return undefined;\n }\n return entry.value as T;\n }\n\n set<T>(key: string, value: T, ttlMs: number): void {\n this.store.set(key, { value, expiresAt: Date.now() + ttlMs });\n }\n\n invalidateByPrefix(prefix: string): void {\n for (const key of this.store.keys()) {\n if (key.startsWith(prefix)) {\n this.store.delete(key);\n }\n }\n }\n\n clear(): void {\n this.store.clear();\n }\n}\n","export class DatabrainApiError extends Error {\n constructor(\n public readonly status: number,\n public readonly code: string,\n message: string,\n public readonly details?: unknown,\n ) {\n super(message);\n this.name = 'DatabrainApiError';\n }\n\n toToolResponse(): { content: Array<{ type: 'text'; text: string }>; isError: true } {\n return {\n content: [{ type: 'text', text: `Error: ${this.message}\\n\\n${this.hint()}` }],\n isError: true,\n };\n }\n\n private hint(): string {\n if (this.status === 401 || this.status === 403) {\n if (this.code === 'INVALID_SERVICE_TOKEN' || this.message.toLowerCase().includes('service token')) {\n return 'Hint: Your service token may be invalid or expired. Generate a new one at Settings > Service Tokens in the Databrain UI.';\n }\n return 'Hint: Your API token may be invalid or expired. Use the `create_api_token` tool to generate a new one, or set DATABRAIN_API_TOKEN in your environment.';\n }\n if (this.status === 404) {\n return 'Hint: The requested resource was not found. Verify the ID or name is correct using the corresponding list tool.';\n }\n if (this.status === 409) {\n return 'Hint: A resource with this name already exists. Use a different name or list existing resources first.';\n }\n if (this.status === 422) {\n return 'Hint: The request parameters are invalid. Check the required fields and their formats.';\n }\n if (this.status === 429) {\n return 'Hint: API rate limit reached. Wait a moment and try again.';\n }\n if (this.status >= 500) {\n return 'Hint: The Databrain API is experiencing issues. Try again in a few moments.';\n }\n return '';\n }\n}\n\nexport function toolError(message: string): { content: Array<{ type: 'text'; text: string }>; isError: true } {\n return {\n content: [{ type: 'text', text: message }],\n isError: true,\n };\n}\n\nexport function stringify(value: unknown): string {\n if (typeof value === 'string') return value;\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n}\n\nexport function toolSuccess(text: string): { content: Array<{ type: 'text'; text: string }> } {\n return {\n content: [{ type: 'text', text }],\n };\n}\n","const LOG_LEVELS = { debug: 0, info: 1, warn: 2, error: 3 } as const;\ntype LogLevel = keyof typeof LOG_LEVELS;\n\nconst currentLevel: LogLevel =\n (process.env.DATABRAIN_LOG_LEVEL as LogLevel) || 'warn';\n\nfunction log(level: LogLevel, message: string, data?: unknown): void {\n if (LOG_LEVELS[level] < LOG_LEVELS[currentLevel]) return;\n const line = `[databrain-mcp] [${level.toUpperCase()}] ${message}`;\n if (data !== undefined) {\n process.stderr.write(`${line} ${JSON.stringify(data)}\\n`);\n } else {\n process.stderr.write(`${line}\\n`);\n }\n}\n\nexport const logger = {\n debug: (msg: string, data?: unknown) => log('debug', msg, data),\n info: (msg: string, data?: unknown) => log('info', msg, data),\n warn: (msg: string, data?: unknown) => log('warn', msg, data),\n error: (msg: string, data?: unknown) => log('error', msg, data),\n};\n","import { TtlCache } from '../utils/cache.js';\nimport type { Config } from '../utils/config.js';\nimport { DatabrainApiError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport type { RequestOptions } from './types.js';\n\nconst MAX_RETRIES = 3;\nconst REQUEST_TIMEOUT_MS = 30_000;\n\nexport class DatabrainClient {\n private cache = new TtlCache();\n private runtimeApiToken: string | undefined;\n\n constructor(private config: Config) {}\n\n hasApiToken(): boolean {\n return !!(this.runtimeApiToken || this.config.apiToken);\n }\n\n setRuntimeApiToken(token: string): void {\n this.runtimeApiToken = token;\n logger.info('Runtime API token set for this session');\n }\n\n private getToken(auth: 'service' | 'api' | 'none'): string | undefined {\n if (auth === 'none') return undefined;\n if (auth === 'service') return this.config.serviceToken;\n return this.runtimeApiToken || this.config.apiToken;\n }\n\n async request<T>(options: RequestOptions): Promise<T> {\n // Invalidate caches first\n if (options.invalidateCache) {\n for (const prefix of options.invalidateCache) {\n this.cache.invalidateByPrefix(prefix);\n }\n }\n\n // Check cache\n if (options.cacheKey && options.cacheTtlMs) {\n const cached = this.cache.get<T>(options.cacheKey);\n if (cached !== undefined) {\n logger.debug(`Cache hit: ${options.cacheKey}`);\n return cached;\n }\n }\n\n const token = this.getToken(options.auth);\n if (options.auth !== 'none' && !token) {\n const tokenType = options.auth === 'service' ? 'DATABRAIN_SERVICE_TOKEN' : 'DATABRAIN_API_TOKEN';\n throw new DatabrainApiError(\n 401,\n 'MISSING_TOKEN',\n `${tokenType} is required for this operation but is not configured.${\n options.auth === 'api'\n ? ' Use the `create_api_token` tool to generate one.'\n : ' Set it in your MCP server environment variables.'\n }`,\n );\n }\n\n // Build URL\n let url = `${this.config.apiUrl}${options.path}`;\n if (options.query) {\n const params = new URLSearchParams(options.query);\n url += `?${params.toString()}`;\n }\n\n let lastError: Error | undefined;\n\n for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {\n try {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n };\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n const response = await fetch(url, {\n method: options.method,\n headers,\n body: options.body ? JSON.stringify(options.body) : undefined,\n signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\n });\n\n if (!response.ok) {\n const errorBody = await response.text();\n logger.warn(`[API Error] ${options.method} ${options.path} status=${response.status} body=${errorBody.slice(0, 500)}`);\n let parsed: { error?: string; message?: string; code?: string; detail?: string } = {};\n try {\n parsed = JSON.parse(errorBody);\n } catch {\n // not JSON\n }\n\n const errorMsg = parsed.message || parsed.detail || (typeof parsed.error === 'string' ? parsed.error : JSON.stringify(parsed.error)) || `API request failed with status ${response.status}`;\n const error = new DatabrainApiError(\n response.status,\n parsed.code || `HTTP_${response.status}`,\n errorMsg,\n parsed,\n );\n\n // Retry on 429 or 5xx\n if ((response.status === 429 || response.status >= 500) && attempt < MAX_RETRIES) {\n const delay = Math.min(1000 * Math.pow(2, attempt - 1), 8000);\n logger.warn(`Retrying in ${delay}ms (attempt ${attempt}/${MAX_RETRIES})`, {\n status: response.status,\n path: options.path,\n });\n await new Promise((r) => setTimeout(r, delay));\n lastError = error;\n continue;\n }\n\n throw error;\n }\n\n const text = await response.text();\n let data = text ? (JSON.parse(text) as T) : ({} as T);\n\n // Databrain API wraps list responses in { data: [...] } — unwrap automatically\n if (data && typeof data === 'object' && !Array.isArray(data) && 'data' in data) {\n const inner = (data as Record<string, unknown>).data;\n if (Array.isArray(inner)) {\n data = inner as unknown as T;\n }\n }\n\n // Store in cache\n if (options.cacheKey && options.cacheTtlMs) {\n this.cache.set(options.cacheKey, data, options.cacheTtlMs);\n }\n\n return data;\n } catch (err) {\n if (err instanceof DatabrainApiError) throw err;\n\n if (attempt < MAX_RETRIES && (err as Error)?.name === 'TimeoutError') {\n const delay = Math.min(1000 * Math.pow(2, attempt - 1), 8000);\n logger.warn(`Request timed out, retrying in ${delay}ms`, { path: options.path });\n await new Promise((r) => setTimeout(r, delay));\n lastError = err as Error;\n continue;\n }\n\n throw new DatabrainApiError(\n 0,\n 'NETWORK_ERROR',\n `Failed to connect to Databrain API: ${(err as Error).message}`,\n );\n }\n }\n\n throw lastError || new DatabrainApiError(0, 'UNKNOWN', 'Request failed after retries');\n }\n}\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerListDatasources(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'list_datasources',\n 'List all connected datasources in your Databrain organization.',\n {},\n async () => {\n try {\n const result = await client.request<unknown[]>({\n method: 'GET',\n path: '/api/v2/datasource/',\n auth: 'service',\n cacheKey: 'list_datasources',\n cacheTtlMs: 10 * 60 * 1000,\n });\n\n if (!Array.isArray(result) || result.length === 0) {\n return toolSuccess(\n 'No datasources found. Use `create_datasource` to connect your first database.'\n );\n }\n\n const formatted = result.map((ds: any) =>\n `- **${ds.name}** (${ds.dbName || ds.datasourceType || 'unknown'}) — ID: ${ds._id || ds.id}`\n ).join('\\n');\n\n return toolSuccess(`Found ${result.length} datasource(s):\\n\\n${formatted}`);\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerCreateDataApp(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'create_data_app',\n 'Create a new data app — a logical container for embeds, tokens, and dashboards.',\n {\n name: z.string().describe('Unique alphanumeric name for the data app'),\n },\n async (params) => {\n try {\n const result = await client.request<{ name: string }>({\n method: 'POST',\n path: '/api/v2/data-app/',\n body: { name: params.name },\n auth: 'service',\n invalidateCache: ['list_data_apps'],\n });\n\n return toolSuccess(\n `Data app \"${result.name}\" created successfully.\\n\\n` +\n 'Next steps:\\n' +\n '1. Use `create_api_token` to generate an API token scoped to this data app\\n' +\n '2. Use `create_datamart` to select tables for analytics'\n );\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerListDataApps(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'list_data_apps',\n 'List all data apps in your Databrain organization.',\n {\n workspaceName: z.string().optional().describe('Filter by workspace name'),\n },\n async (params) => {\n try {\n const query: Record<string, string> = {};\n if (params.workspaceName) query.workspaceName = params.workspaceName;\n\n const result = await client.request<unknown[]>({\n method: 'GET',\n path: '/api/v2/data-app/',\n auth: 'service',\n query: Object.keys(query).length > 0 ? query : undefined,\n cacheKey: 'list_data_apps',\n cacheTtlMs: 10 * 60 * 1000,\n });\n\n if (!Array.isArray(result) || result.length === 0) {\n return toolSuccess(\n 'No data apps found. Use `create_data_app` to create your first data app.'\n );\n }\n\n const formatted = result.map((app: any) =>\n `- **${app.name}** — ID: ${app._id || app.id}${app.workspaceName ? ` (workspace: ${app.workspaceName})` : ''}`\n ).join('\\n');\n\n return toolSuccess(`Found ${result.length} data app(s):\\n\\n${formatted}`);\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerCreateApiToken(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'create_api_token',\n 'Create an API token scoped to a data app. The token is shown once — save it securely. The server will use it for subsequent embed/guest-token operations in this session.',\n {\n dataAppName: z.string().describe('Name of the data app to scope the token to'),\n name: z.string().describe('Descriptive label for the token (e.g., \"Production API Key\")'),\n },\n async (params) => {\n try {\n const result = await client.request<{ key: string }>({\n method: 'POST',\n path: '/api/v2/data-app/api-tokens',\n body: { dataAppName: params.dataAppName, name: params.name },\n auth: 'service',\n });\n\n // Store the token for subsequent operations in this session\n client.setRuntimeApiToken(result.key);\n\n return toolSuccess(\n `API token created successfully for data app \"${params.dataAppName}\".\\n\\n` +\n `**Token:** \\`${result.key}\\`\\n\\n` +\n '⚠️ **IMPORTANT:** Save this token securely — it will not be shown again.\\n\\n' +\n 'This token has been set for use in this session. You can also set it as the ' +\n '`DATABRAIN_API_TOKEN` environment variable for future sessions.\\n\\n' +\n 'Next steps:\\n' +\n '1. Use `create_embed` to configure an embed\\n' +\n '2. Use `generate_guest_token` to create frontend auth tokens'\n );\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerListApiTokens(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'list_api_tokens',\n 'List API tokens for a data app.',\n {\n dataAppName: z.string().describe('Name of the data app'),\n },\n async (params) => {\n try {\n const result = await client.request<unknown[]>({\n method: 'GET',\n path: '/api/v2/data-app/api-tokens',\n auth: 'service',\n query: { dataAppName: params.dataAppName },\n });\n\n if (!Array.isArray(result) || result.length === 0) {\n return toolSuccess(\n 'No API tokens found for this data app. Use `create_api_token` to create one.'\n );\n }\n\n const formatted = result.map((t: any) =>\n `- **${t.name || 'Unnamed'}** — Created: ${t.createdAt || 'N/A'}${t.lastUsedAt ? ` | Last used: ${t.lastUsedAt}` : ''}`\n ).join('\\n');\n\n return toolSuccess(`Found ${result.length} API token(s):\\n\\n${formatted}`);\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerRotateApiToken(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'rotate_api_token',\n 'Rotate an API token for a data app. The old token is immediately invalidated.',\n {\n dataAppName: z.string().describe('Name of the data app'),\n },\n async (params) => {\n try {\n const result = await client.request<{ key: string }>({\n method: 'POST',\n path: '/api/v2/data-app/api-tokens/rotate',\n body: { dataAppName: params.dataAppName },\n auth: 'service',\n });\n\n client.setRuntimeApiToken(result.key);\n\n return toolSuccess(\n `API token rotated successfully for \"${params.dataAppName}\".\\n\\n` +\n `**New Token:** \\`${result.key}\\`\\n\\n` +\n 'The old token is now invalid. This new token has been set for this session.\\n' +\n 'Save it securely — it will not be shown again.'\n );\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerListDatamarts(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'list_datamarts',\n 'List datamarts with table and schema information.',\n {\n dataAppName: z.string().optional().describe('Filter by data app name'),\n },\n async (params) => {\n try {\n const query: Record<string, string> = {};\n if (params.dataAppName) query.dataAppName = params.dataAppName;\n\n const result = await client.request<unknown[]>({\n method: 'GET',\n path: '/api/v2/data-app/datamarts',\n auth: 'service',\n query: Object.keys(query).length > 0 ? query : undefined,\n cacheKey: 'list_datamarts',\n cacheTtlMs: 10 * 60 * 1000,\n });\n\n if (!Array.isArray(result) || result.length === 0) {\n return toolSuccess(\n 'No datamarts found. Use `create_datamart` to create one from your datasource.'\n );\n }\n\n const formatted = result.map((dm: any) => {\n const tables = dm.tableList?.map((t: any) => t.name).join(', ') || 'N/A';\n const score = dm.semanticLayerCompletionScore;\n return `- **${dm.name}** (ID: ${dm._id || dm.id}) — Tables: ${tables}${score !== undefined ? ` | Semantic Layer: ${score}%` : ''}`;\n }).join('\\n');\n\n return toolSuccess(`Found ${result.length} datamart(s):\\n\\n${formatted}`);\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerGetSemanticLayerStatus(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'get_semantic_layer_status',\n 'Check progress of a semantic layer generation job.',\n {\n datamartId: z.string().describe('ID of the datamart'),\n },\n async (params) => {\n try {\n const result = await client.request<{\n status?: string;\n progress?: number;\n tablesProcessed?: number;\n totalTables?: number;\n error?: string;\n }>({\n method: 'GET',\n path: `/api/schema/datamart/${params.datamartId}/semantic-layer/generation-status`,\n auth: 'service',\n });\n\n if (result.error) {\n return toolError(`Semantic layer generation failed: ${result.error}`);\n }\n\n const progress = result.progress !== undefined ? `${result.progress}%` : 'unknown';\n const tables = result.tablesProcessed !== undefined && result.totalTables !== undefined\n ? `${result.tablesProcessed}/${result.totalTables} tables`\n : '';\n\n return toolSuccess(\n `Semantic Layer Generation Status\\n\\n` +\n `Status: ${result.status || 'unknown'}\\n` +\n `Progress: ${progress}\\n` +\n (tables ? `Tables: ${tables}\\n` : '') +\n (result.status === 'completed'\n ? '\\nSemantic layer is ready! AI chat mode will now work with this datamart.'\n : '\\nUse this tool again to check updated progress.')\n );\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess, stringify } from '../../utils/errors.js';\n\nconst accessSettingsSchema = z.object({\n datamartName: z.string(),\n isAllowAiPilot: z.boolean().optional().default(false),\n isAllowEmailReports: z.boolean(),\n isAllowManageMetrics: z.boolean(),\n isAllowCreateDashboardView: z.boolean(),\n isAllowMetricCreation: z.boolean(),\n isAllowMetricDeletion: z.boolean(),\n isAllowMetricLayoutChange: z.boolean(),\n isAllowMetricUpdate: z.boolean(),\n isAllowUnderlyingData: z.boolean(),\n metricCreationMode: z.enum(['DRAG_DROP', 'CHAT']),\n joinModel: z.enum(['single', 'multi']).optional().default('multi'),\n tableTenancySettings: z.array(z.object({\n name: z.string(),\n clientColumn: z.string(),\n })).optional(),\n});\n\nexport function registerCreateEmbed(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'create_embed',\n 'Create an embed configuration for a dashboard or metric. Requires an API token.',\n {\n dashboardId: z.string().describe('ID of the dashboard to embed'),\n embedType: z.enum(['dashboard', 'metric']).describe('Type of embed'),\n workspaceName: z.string().describe('Workspace name'),\n metricId: z.string().optional().describe('Required if embedType is \"metric\"'),\n name: z.string().optional().describe('Human-readable name for the embed'),\n accessSettings: accessSettingsSchema.describe('Access and permission settings for the embed'),\n },\n async (params) => {\n try {\n const result = await client.request<{ id: string; error?: string }>({\n method: 'POST',\n path: '/api/v2/data-app/embeds',\n body: params,\n auth: 'api',\n invalidateCache: ['list_embeds'],\n });\n\n if (result.error) {\n return toolError(`Embed creation failed: ${stringify(result.error)}`);\n }\n\n return toolSuccess(\n `Embed created successfully (ID: ${result.id}).\\n\\n` +\n 'Next steps:\\n' +\n '1. Use `generate_guest_token` to create a frontend auth token\\n' +\n '2. Use `generate_embed_code` to get copy-paste-ready frontend code'\n );\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerListEmbeds(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'list_embeds',\n 'List all embed configurations. Requires an API token.',\n {\n dataAppName: z.string().optional().describe('Filter by data app name'),\n },\n async (params) => {\n try {\n const query: Record<string, string> = {};\n if (params.dataAppName) query.dataAppName = params.dataAppName;\n\n const result = await client.request<unknown[]>({\n method: 'GET',\n path: '/api/v2/data-app/embeds',\n auth: 'api',\n query: Object.keys(query).length > 0 ? query : undefined,\n cacheKey: 'list_embeds',\n cacheTtlMs: 5 * 60 * 1000,\n });\n\n if (!Array.isArray(result) || result.length === 0) {\n return toolSuccess(\n 'No embeds found. Use `create_embed` to create your first embed configuration.'\n );\n }\n\n const formatted = result.map((e: any) => {\n const id = e.embedId || e._id || e.id;\n const name = e.name || e.externalDashboard?.name || 'Unnamed';\n const dashId = e.embedMetadata?.dashboardId || e.dashboardId;\n const dataApp = e.embedMetadata?.dataAppName;\n return `- **${name}** (${e.embedType || 'dashboard'}) — Embed ID: \\`${id}\\`${dashId ? ` | Dashboard: ${dashId}` : ''}${dataApp ? ` | Data App: ${dataApp}` : ''}`;\n }).join('\\n');\n\n return toolSuccess(`Found ${result.length} embed(s):\\n\\n${formatted}`);\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerGetEmbedDetails(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'get_embed_details',\n 'Get detailed configuration for a specific embed, including all access settings.',\n {\n embedId: z.string().describe('ID of the embed'),\n },\n async (params) => {\n try {\n const result = await client.request<Record<string, unknown>>({\n method: 'GET',\n path: '/api/v2/data-app/embeds',\n auth: 'api',\n query: { embedId: params.embedId },\n });\n\n return toolSuccess(\n `Embed Details (ID: ${params.embedId})\\n\\n` +\n '```json\\n' +\n JSON.stringify(result, null, 2) +\n '\\n```'\n );\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess, stringify } from '../../utils/errors.js';\n\nexport function registerUpdateEmbed(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'update_embed',\n 'Update embed configuration — access settings, permissions, theme, or name.',\n {\n embedId: z.string().describe('ID of the embed to update'),\n name: z.string().optional().describe('New name for the embed'),\n accessSettings: z.record(z.unknown()).optional().describe(\n 'Partial update of access settings. See `get_embed_details` for current settings.'\n ),\n theme: z.record(z.unknown()).optional().describe(\n 'Theme configuration object. See databrain://theme-reference for the full schema.'\n ),\n },\n async (params) => {\n try {\n const body: Record<string, unknown> = { embedId: params.embedId };\n if (params.name) body.name = params.name;\n if (params.accessSettings) body.accessSettings = params.accessSettings;\n if (params.theme) body.theme = params.theme;\n\n const result = await client.request<Record<string, unknown>>({\n method: 'PUT',\n path: '/api/v2/data-app/embeds',\n body,\n auth: 'api',\n invalidateCache: ['list_embeds'],\n });\n\n if (result.error) {\n return toolError(`Embed update failed: ${stringify(result.error)}`);\n }\n\n return toolSuccess(`Embed \"${params.embedId}\" updated successfully.`);\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerDeleteEmbed(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'delete_embed',\n 'Delete an embed configuration. This is irreversible.',\n {\n embedId: z.string().describe('ID of the embed to delete'),\n },\n async (params) => {\n try {\n await client.request<unknown>({\n method: 'DELETE',\n path: `/api/v2/data-app/embeds/${params.embedId}`,\n auth: 'api',\n invalidateCache: ['list_embeds'],\n });\n\n return toolSuccess(`Embed \"${params.embedId}\" deleted successfully.`);\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerRenameEmbed(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'rename_embed',\n 'Rename an embed configuration.',\n {\n embedId: z.string().describe('ID of the embed to rename'),\n name: z.string().describe('New name for the embed'),\n },\n async (params) => {\n try {\n await client.request<unknown>({\n method: 'PUT',\n path: `/api/v2/data-app/embeds/${params.embedId}/rename`,\n body: { name: params.name },\n auth: 'api',\n invalidateCache: ['list_embeds'],\n });\n\n return toolSuccess(`Embed renamed to \"${params.name}\" successfully.`);\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess, stringify } from '../../utils/errors.js';\n\nconst THEME_PRESETS: Record<string, Record<string, unknown>> = {\n light: {\n general: {\n fontFamily: 'Inter, sans-serif',\n backgroundColor: '#ffffff',\n primaryColor: '#4F46E5',\n secondaryColor: '#10B981',\n textColor: '#1F2937',\n borderColor: '#E5E7EB',\n borderRadius: '8px',\n },\n dashboard: { backgroundColor: '#F9FAFB', padding: '24px', gap: '16px' },\n chart: {\n colorPalette: ['#4F46E5', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6', '#06B6D4'],\n axisColor: '#9CA3AF',\n gridColor: '#F3F4F6',\n },\n cardCustomization: {\n backgroundColor: '#FFFFFF',\n borderColor: '#E5E7EB',\n borderRadius: '12px',\n shadow: '0 1px 3px rgba(0,0,0,0.1)',\n },\n },\n dark: {\n general: {\n fontFamily: 'Inter, sans-serif',\n backgroundColor: '#111827',\n primaryColor: '#818CF8',\n secondaryColor: '#34D399',\n textColor: '#F9FAFB',\n borderColor: '#374151',\n borderRadius: '8px',\n },\n dashboard: { backgroundColor: '#0F172A', padding: '24px', gap: '16px' },\n chart: {\n colorPalette: ['#818CF8', '#34D399', '#FBBF24', '#F87171', '#A78BFA', '#22D3EE'],\n axisColor: '#6B7280',\n gridColor: '#1F2937',\n tooltipBackground: '#F9FAFB',\n tooltipTextColor: '#111827',\n },\n cardTitle: { color: '#F9FAFB' },\n cardDescription: { color: '#9CA3AF' },\n cardCustomization: {\n backgroundColor: '#1F2937',\n borderColor: '#374151',\n borderRadius: '12px',\n shadow: '0 1px 3px rgba(0,0,0,0.3)',\n },\n },\n corporate: {\n general: {\n fontFamily: '\"IBM Plex Sans\", sans-serif',\n backgroundColor: '#FAFAFA',\n primaryColor: '#1E40AF',\n secondaryColor: '#059669',\n textColor: '#1E293B',\n borderColor: '#CBD5E1',\n borderRadius: '4px',\n },\n dashboard: { backgroundColor: '#F1F5F9', padding: '20px', gap: '12px' },\n chart: {\n colorPalette: ['#1E40AF', '#059669', '#D97706', '#DC2626', '#7C3AED', '#0891B2'],\n axisColor: '#94A3B8',\n gridColor: '#E2E8F0',\n },\n cardCustomization: {\n backgroundColor: '#FFFFFF',\n borderColor: '#CBD5E1',\n borderRadius: '4px',\n shadow: 'none',\n },\n },\n minimal: {\n general: {\n fontFamily: 'system-ui, sans-serif',\n backgroundColor: '#FFFFFF',\n primaryColor: '#171717',\n secondaryColor: '#525252',\n textColor: '#171717',\n borderColor: '#E5E5E5',\n borderRadius: '0px',\n },\n dashboard: { backgroundColor: '#FFFFFF', padding: '16px', gap: '8px' },\n chart: {\n colorPalette: ['#171717', '#525252', '#737373', '#A3A3A3', '#D4D4D4'],\n axisColor: '#D4D4D4',\n gridColor: '#F5F5F5',\n },\n cardCustomization: {\n backgroundColor: '#FFFFFF',\n borderColor: '#E5E5E5',\n borderRadius: '0px',\n shadow: 'none',\n },\n },\n};\n\nconst ACCESS_PRESETS: Record<string, Record<string, unknown>> = {\n 'view-only': {\n isAllowMetricCreation: false,\n isAllowMetricDeletion: false,\n isAllowMetricEditing: false,\n isAllowChangeLayout: false,\n isAllowDrillDown: false,\n isAllowDashboardFilters: true,\n isAllowDownloadCsv: false,\n isAllowAiPilot: false,\n },\n 'power-user': {\n isAllowMetricCreation: true,\n isAllowMetricEditing: true,\n isAllowMetricDeletion: true,\n isAllowChangeLayout: true,\n isAllowDrillDown: true,\n isAllowCrossFilter: true,\n isAllowAiPilot: true,\n isAllowAiSummary: true,\n isAllowDownloadCsv: true,\n isAllowDownloadPdf: true,\n isAllowDashboardFilters: true,\n metricCreationMode: 'CHAT',\n },\n 'export-only': {\n isAllowMetricCreation: false,\n isAllowMetricEditing: false,\n isAllowDrillDown: true,\n isAllowDownloadCsv: true,\n isAllowEmailCsv: true,\n isAllowDownloadAllMetrics: true,\n isAllowDownloadPdf: true,\n isAllowDashboardFilters: true,\n },\n 'ai-enabled': {\n isAllowMetricCreation: true,\n isAllowAiPilot: true,\n isAllowAiSummary: true,\n isAllowAiRecommendation: true,\n isAllowDrillDown: true,\n isAllowDashboardFilters: true,\n metricCreationMode: 'CHAT',\n },\n};\n\nexport function registerApplyThemePreset(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'apply_embed_preset',\n `Apply a theme and/or access preset to an embed. Theme presets: ${Object.keys(THEME_PRESETS).join(', ')}. Access presets: ${Object.keys(ACCESS_PRESETS).join(', ')}. You can apply one or both.`,\n {\n embedId: z.string().describe('ID of the embed to update'),\n themePreset: z.enum(['light', 'dark', 'corporate', 'minimal']).optional()\n .describe('Theme preset to apply'),\n accessPreset: z.enum(['view-only', 'power-user', 'export-only', 'ai-enabled']).optional()\n .describe('Access settings preset to apply'),\n },\n async (params) => {\n if (!params.themePreset && !params.accessPreset) {\n return toolError('Provide at least one of themePreset or accessPreset.');\n }\n\n try {\n const body: Record<string, unknown> = { embedId: params.embedId };\n\n if (params.themePreset) {\n body.theme = THEME_PRESETS[params.themePreset];\n }\n if (params.accessPreset) {\n body.accessSettings = ACCESS_PRESETS[params.accessPreset];\n }\n\n const result = await client.request<Record<string, unknown>>({\n method: 'PUT',\n path: '/api/v2/data-app/embeds',\n body,\n auth: 'api',\n invalidateCache: ['list_embeds'],\n });\n\n if (result.error) {\n return toolError(`Failed to apply preset: ${stringify(result.error)}`);\n }\n\n const applied: string[] = [];\n if (params.themePreset) applied.push(`theme: **${params.themePreset}**`);\n if (params.accessPreset) applied.push(`access: **${params.accessPreset}**`);\n\n let details = '';\n if (params.accessPreset) {\n const settings = ACCESS_PRESETS[params.accessPreset];\n const enabled = Object.entries(settings)\n .filter(([, v]) => v === true)\n .map(([k]) => k)\n .join(', ');\n details = `\\n\\nEnabled settings: ${enabled || 'none'}`;\n if (settings.metricCreationMode) {\n details += `\\nMetric creation mode: ${settings.metricCreationMode}`;\n }\n }\n\n return toolSuccess(\n `Preset applied to embed \"${params.embedId}\": ${applied.join(', ')}.${details}`\n );\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerGenerateGuestToken(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'generate_guest_token',\n 'Generate a guest token for frontend embedding. This token authenticates end-users to view embedded dashboards.',\n {\n clientId: z.string().describe('Unique end-user identifier for multi-tenant filtering'),\n dataAppName: z.string().describe('Name of the data app'),\n params: z.object({\n allowedEmbeds: z.array(z.string()).optional().describe('Array of embed IDs to whitelist'),\n timezone: z.string().optional().describe('Timezone, e.g. \"America/New_York\"'),\n appFilters: z.array(z.object({\n metricId: z.string(),\n values: z.array(z.unknown()),\n })).optional(),\n dashboardAppFilters: z.array(z.object({\n dashboardId: z.string(),\n values: z.array(z.unknown()),\n })).optional(),\n permissions: z.object({\n isEnableArchiveMetrics: z.boolean().optional(),\n isEnableManageMetrics: z.boolean().optional(),\n isEnableCreateDashboardView: z.boolean().optional(),\n isEnableMetricUpdation: z.boolean().optional(),\n isEnableCustomizeLayout: z.boolean().optional(),\n isEnableUnderlyingData: z.boolean().optional(),\n isEnableDownloadMetrics: z.boolean().optional(),\n isShowSideBar: z.boolean().optional(),\n isShowDashboardName: z.boolean().optional(),\n isDisableMetricCreation: z.boolean().optional(),\n }).optional(),\n hideDashboardFilters: z.array(z.string()).optional(),\n expiryTime: z.number().optional().describe('Token TTL in milliseconds'),\n datasourceName: z.string().optional(),\n userIdentifier: z.string().optional(),\n }).optional().describe('Optional token parameters'),\n },\n async (params) => {\n try {\n const result = await client.request<{ token: string }>({\n method: 'POST',\n path: '/api/v2/guest-token/create',\n body: {\n clientId: params.clientId,\n dataAppName: params.dataAppName,\n ...params.params,\n },\n auth: 'api',\n });\n\n return toolSuccess(\n `Guest token generated successfully.\\n\\n` +\n `**Token:** \\`${result.token}\\`\\n\\n` +\n 'Use this token in the frontend `<dbn-dashboard>` or `<dbn-metric>` web component\\'s `token` attribute.\\n\\n' +\n 'Next step: Use `generate_embed_code` to get copy-paste-ready frontend code.'\n );\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { toolSuccess } from '../../utils/errors.js';\nimport { getTemplate } from '../../templates/index.js';\nimport type { TemplateContext } from '../../templates/types.js';\n\nconst FRAMEWORKS = ['react', 'nextjs', 'vue', 'angular', 'svelte', 'solidjs', 'vanilla'] as const;\n\nexport function registerGenerateEmbedCode(server: McpServer, _client: DatabrainClient): void {\n server.tool(\n 'generate_embed_code',\n 'Generate framework-specific, copy-paste-ready code to embed a Databrain dashboard or metric. No API call — generates code locally.',\n {\n embedId: z.string().describe('The embed ID to generate code for'),\n framework: z.enum(FRAMEWORKS).describe('Frontend framework'),\n embedType: z.enum(['dashboard', 'metric']).optional().default('dashboard'),\n options: z.object({\n enableDownloadCsv: z.boolean().optional(),\n enableEmailCsv: z.boolean().optional(),\n enableDownloadAllMetrics: z.boolean().optional(),\n enableDownloadAllPdf: z.boolean().optional(),\n disableFullscreen: z.boolean().optional(),\n isHideTablePreview: z.boolean().optional(),\n isHideChartSettings: z.boolean().optional(),\n isStickyDashboardFilters: z.boolean().optional(),\n enableMultiMetricFilters: z.boolean().optional(),\n themeName: z.string().optional(),\n customTheme: z.record(z.unknown()).optional(),\n optionsIcon: z.enum(['kebab-menu-vertical', 'download']).optional(),\n }).optional(),\n },\n async (params) => {\n const ctx: TemplateContext = {\n embedId: params.embedId,\n embedType: params.embedType || 'dashboard',\n options: params.options || {},\n };\n\n const generated = getTemplate(params.framework, ctx);\n\n let output = `## ${params.framework.charAt(0).toUpperCase() + params.framework.slice(1)} Embed Code\\n\\n`;\n\n output += `### 1. Install Dependencies\\n\\`\\`\\`bash\\n${generated.installCommand}\\n\\`\\`\\`\\n\\n`;\n\n output += `### 2. Backend — Guest Token API Route\\n\\`\\`\\`${generated.backendLanguage || 'typescript'}\\n${generated.backendCode}\\n\\`\\`\\`\\n\\n`;\n\n output += `### 3. Frontend Component\\n\\`\\`\\`${generated.frontendLanguage || 'tsx'}\\n${generated.frontendCode}\\n\\`\\`\\`\\n\\n`;\n\n output += `### 4. Setup Instructions\\n${generated.instructions}`;\n\n return toolSuccess(output);\n },\n );\n}\n","import type { TemplateContext, GeneratedCode } from './types.js';\n\nfunction kebabCase(str: string): string {\n return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();\n}\n\nfunction buildAttributes(ctx: TemplateContext) {\n const tag = ctx.embedType === 'dashboard' ? 'dbn-dashboard' : 'dbn-metric';\n const idAttr = ctx.embedType === 'dashboard' ? 'dashboard-id' : 'metric-id';\n const boolAttrs = Object.entries(ctx.options)\n .filter(([_, v]) => v === true)\n .map(([k]) => kebabCase(k))\n .join(' ');\n return { tag, idAttr, boolAttrs };\n}\n\nexport function reactTemplate(ctx: TemplateContext): GeneratedCode {\n const { tag, idAttr, boolAttrs } = buildAttributes(ctx);\n const boolAttrString = boolAttrs ? ` ${boolAttrs}` : '';\n\n const installCommand = 'npm install @databrainhq/plugin';\n\n const backendCode = `// server.ts - Express backend\nimport express from 'express';\nimport cors from 'cors';\n\nconst app = express();\napp.use(cors());\napp.use(express.json());\n\napp.post('/api/guest-token', async (req, res) => {\n const { clientId } = req.body;\n\n try {\n const response = await fetch(\n \\`\\${process.env.DATABRAIN_API_URL}/api/v2/guest-token/create\\`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: \\`Bearer \\${process.env.DATABRAIN_API_TOKEN}\\`,\n },\n body: JSON.stringify({ clientId }),\n }\n );\n\n const data = await response.json();\n res.json(data);\n } catch (error) {\n console.error('Error creating guest token:', error);\n res.status(500).json({ error: 'Failed to create guest token' });\n }\n});\n\napp.listen(3001, () => {\n console.log('Server running on http://localhost:3001');\n});`;\n\n const frontendCode = `// DatabrainEmbed.tsx - React component\nimport { useEffect, useState } from 'react';\nimport '@databrainhq/plugin';\n\nexport default function DatabrainEmbed() {\n const [token, setToken] = useState<string | null>(null);\n\n useEffect(() => {\n async function fetchToken() {\n try {\n const response = await fetch('/api/guest-token', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ clientId: 'your-client-id' }),\n });\n const data = await response.json();\n setToken(data.token);\n } catch (error) {\n console.error('Failed to fetch guest token:', error);\n }\n }\n\n fetchToken();\n }, []);\n\n if (!token) return <div>Loading...</div>;\n\n return (\n <${tag}\n token={token}\n ${idAttr}=\"${ctx.embedId}\"${boolAttrString}\n />\n );\n}`;\n\n const instructions = `## React + Express Setup\n\n### Environment Variables\nSet the following environment variables on your backend server:\n- \\`DATABRAIN_API_TOKEN\\` - Your Databrain API token\n- \\`DATABRAIN_API_URL\\` - Your Databrain API base URL (e.g. https://app.usedatabrain.com)\n\n### Security\nThe guest token must be generated server-side. Never expose your DATABRAIN_API_TOKEN to the client.\n\n### Steps\n1. Install the plugin: \\`${installCommand}\\`\n2. Set up the Express backend (server.ts) and start it\n3. Use the DatabrainEmbed component in your React app\n4. Replace 'your-client-id' with the actual client identifier for the logged-in user\n5. If using Create React App or Vite, proxy /api requests to the Express backend`;\n\n return {\n installCommand,\n backendCode,\n backendLanguage: 'typescript',\n frontendCode,\n frontendLanguage: 'tsx',\n instructions,\n };\n}\n","import type { TemplateContext, GeneratedCode } from './types.js';\n\nfunction kebabCase(str: string): string {\n return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();\n}\n\nfunction buildAttributes(ctx: TemplateContext) {\n const tag = ctx.embedType === 'dashboard' ? 'dbn-dashboard' : 'dbn-metric';\n const idAttr = ctx.embedType === 'dashboard' ? 'dashboard-id' : 'metric-id';\n const boolAttrs = Object.entries(ctx.options)\n .filter(([_, v]) => v === true)\n .map(([k]) => kebabCase(k))\n .join(' ');\n return { tag, idAttr, boolAttrs };\n}\n\nexport function nextjsTemplate(ctx: TemplateContext): GeneratedCode {\n const { tag, idAttr, boolAttrs } = buildAttributes(ctx);\n const boolAttrString = boolAttrs ? ` ${boolAttrs}` : '';\n\n const installCommand = 'npm install @databrainhq/plugin';\n\n const backendCode = `// app/api/guest-token/route.ts - Next.js App Router API route\nimport { NextRequest, NextResponse } from 'next/server';\n\nexport async function POST(request: NextRequest) {\n const { clientId } = await request.json();\n\n try {\n const response = await fetch(\n \\`\\${process.env.DATABRAIN_API_URL}/api/v2/guest-token/create\\`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: \\`Bearer \\${process.env.DATABRAIN_API_TOKEN}\\`,\n },\n body: JSON.stringify({ clientId }),\n }\n );\n\n const data = await response.json();\n return NextResponse.json(data);\n } catch (error) {\n console.error('Error creating guest token:', error);\n return NextResponse.json(\n { error: 'Failed to create guest token' },\n { status: 500 }\n );\n }\n}`;\n\n const frontendCode = `// app/components/DatabrainEmbed.tsx - Next.js Client Component\n'use client';\n\nimport { useEffect, useState } from 'react';\nimport '@databrainhq/plugin';\n\nexport default function DatabrainEmbed() {\n const [token, setToken] = useState<string | null>(null);\n\n useEffect(() => {\n async function fetchToken() {\n try {\n const response = await fetch('/api/guest-token', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ clientId: 'your-client-id' }),\n });\n const data = await response.json();\n setToken(data.token);\n } catch (error) {\n console.error('Failed to fetch guest token:', error);\n }\n }\n\n fetchToken();\n }, []);\n\n if (!token) return <div>Loading...</div>;\n\n return (\n <${tag}\n token={token}\n ${idAttr}=\"${ctx.embedId}\"${boolAttrString}\n />\n );\n}`;\n\n const instructions = `## Next.js (App Router) Setup\n\n### Environment Variables\nAdd the following to your \\`.env.local\\` file:\n- \\`DATABRAIN_API_TOKEN\\` - Your Databrain API token\n- \\`DATABRAIN_API_URL\\` - Your Databrain API base URL (e.g. https://app.usedatabrain.com)\n\n### Security\nThe guest token is generated in the API route (server-side). Never expose your DATABRAIN_API_TOKEN to the client.\n\n### Steps\n1. Install the plugin: \\`${installCommand}\\`\n2. Create the API route at \\`app/api/guest-token/route.ts\\`\n3. Create the client component at \\`app/components/DatabrainEmbed.tsx\\`\n4. Import and use the component in your page (it must be used within a client component boundary due to the 'use client' directive)\n5. Replace 'your-client-id' with the actual client identifier for the logged-in user\n6. The \\`@databrainhq/plugin\\` import registers custom elements, so it must run on the client side`;\n\n return {\n installCommand,\n backendCode,\n backendLanguage: 'typescript',\n frontendCode,\n frontendLanguage: 'tsx',\n instructions,\n };\n}\n","import type { TemplateContext, GeneratedCode } from './types.js';\n\nfunction kebabCase(str: string): string {\n return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();\n}\n\nfunction buildAttributes(ctx: TemplateContext) {\n const tag = ctx.embedType === 'dashboard' ? 'dbn-dashboard' : 'dbn-metric';\n const idAttr = ctx.embedType === 'dashboard' ? 'dashboard-id' : 'metric-id';\n const boolAttrs = Object.entries(ctx.options)\n .filter(([_, v]) => v === true)\n .map(([k]) => kebabCase(k))\n .join(' ');\n return { tag, idAttr, boolAttrs };\n}\n\nexport function vueTemplate(ctx: TemplateContext): GeneratedCode {\n const { tag, idAttr, boolAttrs } = buildAttributes(ctx);\n const boolAttrString = boolAttrs ? ` ${boolAttrs}` : '';\n\n const installCommand = 'npm install @databrainhq/plugin';\n\n const backendCode = `// server.ts - Express backend\nimport express from 'express';\nimport cors from 'cors';\n\nconst app = express();\napp.use(cors());\napp.use(express.json());\n\napp.post('/api/guest-token', async (req, res) => {\n const { clientId } = req.body;\n\n try {\n const response = await fetch(\n \\`\\${process.env.DATABRAIN_API_URL}/api/v2/guest-token/create\\`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: \\`Bearer \\${process.env.DATABRAIN_API_TOKEN}\\`,\n },\n body: JSON.stringify({ clientId }),\n }\n );\n\n const data = await response.json();\n res.json(data);\n } catch (error) {\n console.error('Error creating guest token:', error);\n res.status(500).json({ error: 'Failed to create guest token' });\n }\n});\n\napp.listen(3001, () => {\n console.log('Server running on http://localhost:3001');\n});`;\n\n const frontendCode = `<!-- DatabrainEmbed.vue - Vue 3 SFC -->\n<script setup lang=\"ts\">\nimport { ref, onMounted } from 'vue';\nimport '@databrainhq/plugin';\n\nconst token = ref<string | null>(null);\n\nonMounted(async () => {\n try {\n const response = await fetch('/api/guest-token', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ clientId: 'your-client-id' }),\n });\n const data = await response.json();\n token.value = data.token;\n } catch (error) {\n console.error('Failed to fetch guest token:', error);\n }\n});\n</script>\n\n<template>\n <div v-if=\"!token\">Loading...</div>\n <${tag}\n v-else\n :token=\"token\"\n ${idAttr}=\"${ctx.embedId}\"${boolAttrString}\n />\n</template>`;\n\n const instructions = `## Vue 3 + Express Setup\n\n### Environment Variables\nSet the following environment variables on your backend server:\n- \\`DATABRAIN_API_TOKEN\\` - Your Databrain API token\n- \\`DATABRAIN_API_URL\\` - Your Databrain API base URL (e.g. https://app.usedatabrain.com)\n\n### Security\nThe guest token must be generated server-side. Never expose your DATABRAIN_API_TOKEN to the client.\n\n### Steps\n1. Install the plugin: \\`${installCommand}\\`\n2. Set up the Express backend (server.ts) and start it\n3. Add the DatabrainEmbed.vue component to your Vue 3 app\n4. Replace 'your-client-id' with the actual client identifier for the logged-in user\n5. Configure your Vue app to recognize custom elements by adding \\`compilerOptions.isCustomElement\\` in your Vue config:\n \\`\\`\\`ts\n // vite.config.ts\n vue({\n template: {\n compilerOptions: {\n isCustomElement: (tag) => tag.startsWith('dbn-'),\n },\n },\n })\n \\`\\`\\`\n6. Proxy /api requests to the Express backend in your dev server config`;\n\n return {\n installCommand,\n backendCode,\n backendLanguage: 'typescript',\n frontendCode,\n frontendLanguage: 'vue',\n instructions,\n };\n}\n","import type { TemplateContext, GeneratedCode } from './types.js';\n\nfunction kebabCase(str: string): string {\n return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();\n}\n\nfunction buildAttributes(ctx: TemplateContext) {\n const tag = ctx.embedType === 'dashboard' ? 'dbn-dashboard' : 'dbn-metric';\n const idAttr = ctx.embedType === 'dashboard' ? 'dashboard-id' : 'metric-id';\n const boolAttrs = Object.entries(ctx.options)\n .filter(([_, v]) => v === true)\n .map(([k]) => kebabCase(k))\n .join(' ');\n return { tag, idAttr, boolAttrs };\n}\n\nexport function angularTemplate(ctx: TemplateContext): GeneratedCode {\n const { tag, idAttr, boolAttrs } = buildAttributes(ctx);\n const boolAttrString = boolAttrs ? ` ${boolAttrs}` : '';\n\n const installCommand = 'npm install @databrainhq/plugin';\n\n const backendCode = `// server.ts - Express backend\nimport express from 'express';\nimport cors from 'cors';\n\nconst app = express();\napp.use(cors());\napp.use(express.json());\n\napp.post('/api/guest-token', async (req, res) => {\n const { clientId } = req.body;\n\n try {\n const response = await fetch(\n \\`\\${process.env.DATABRAIN_API_URL}/api/v2/guest-token/create\\`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: \\`Bearer \\${process.env.DATABRAIN_API_TOKEN}\\`,\n },\n body: JSON.stringify({ clientId }),\n }\n );\n\n const data = await response.json();\n res.json(data);\n } catch (error) {\n console.error('Error creating guest token:', error);\n res.status(500).json({ error: 'Failed to create guest token' });\n }\n});\n\napp.listen(3001, () => {\n console.log('Server running on http://localhost:3001');\n});`;\n\n const frontendCode = `// databrain-embed.component.ts - Angular component\nimport { Component, OnInit, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport '@databrainhq/plugin';\n\n@Component({\n selector: 'app-databrain-embed',\n standalone: true,\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\n template: \\`\n <div *ngIf=\"!token\">Loading...</div>\n <${tag}\n *ngIf=\"token\"\n [attr.token]=\"token\"\n ${idAttr}=\"${ctx.embedId}\"${boolAttrString}\n />\n \\`,\n})\nexport class DatabrainEmbedComponent implements OnInit {\n token: string | null = null;\n\n constructor(private http: HttpClient) {}\n\n ngOnInit(): void {\n this.http\n .post<{ token: string }>('/api/guest-token', {\n clientId: 'your-client-id',\n })\n .subscribe({\n next: (data) => {\n this.token = data.token;\n },\n error: (error) => {\n console.error('Failed to fetch guest token:', error);\n },\n });\n }\n}`;\n\n const instructions = `## Angular + Express Setup\n\n### Environment Variables\nSet the following environment variables on your backend server:\n- \\`DATABRAIN_API_TOKEN\\` - Your Databrain API token\n- \\`DATABRAIN_API_URL\\` - Your Databrain API base URL (e.g. https://app.usedatabrain.com)\n\n### Security\nThe guest token must be generated server-side. Never expose your DATABRAIN_API_TOKEN to the client.\n\n### Steps\n1. Install the plugin: \\`${installCommand}\\`\n2. Set up the Express backend (server.ts) and start it\n3. Add \\`HttpClientModule\\` to your app's imports (or use \\`provideHttpClient()\\` in standalone apps)\n4. Add the \\`DatabrainEmbedComponent\\` to your Angular app\n5. The component uses \\`CUSTOM_ELEMENTS_SCHEMA\\` to allow the custom web component elements\n6. Replace 'your-client-id' with the actual client identifier for the logged-in user\n7. Configure a proxy for /api requests to the Express backend during development:\n \\`\\`\\`json\n // proxy.conf.json\n {\n \"/api\": {\n \"target\": \"http://localhost:3001\",\n \"secure\": false\n }\n }\n \\`\\`\\``;\n\n return {\n installCommand,\n backendCode,\n backendLanguage: 'typescript',\n frontendCode,\n frontendLanguage: 'typescript',\n instructions,\n };\n}\n","import type { TemplateContext, GeneratedCode } from './types.js';\n\nfunction kebabCase(str: string): string {\n return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();\n}\n\nfunction buildAttributes(ctx: TemplateContext) {\n const tag = ctx.embedType === 'dashboard' ? 'dbn-dashboard' : 'dbn-metric';\n const idAttr = ctx.embedType === 'dashboard' ? 'dashboard-id' : 'metric-id';\n const boolAttrs = Object.entries(ctx.options)\n .filter(([_, v]) => v === true)\n .map(([k]) => kebabCase(k))\n .join(' ');\n return { tag, idAttr, boolAttrs };\n}\n\nexport function svelteTemplate(ctx: TemplateContext): GeneratedCode {\n const { tag, idAttr, boolAttrs } = buildAttributes(ctx);\n const boolAttrString = boolAttrs ? ` ${boolAttrs}` : '';\n\n const installCommand = 'npm install @databrainhq/plugin';\n\n const backendCode = `// server.ts - Express backend\nimport express from 'express';\nimport cors from 'cors';\n\nconst app = express();\napp.use(cors());\napp.use(express.json());\n\napp.post('/api/guest-token', async (req, res) => {\n const { clientId } = req.body;\n\n try {\n const response = await fetch(\n \\`\\${process.env.DATABRAIN_API_URL}/api/v2/guest-token/create\\`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: \\`Bearer \\${process.env.DATABRAIN_API_TOKEN}\\`,\n },\n body: JSON.stringify({ clientId }),\n }\n );\n\n const data = await response.json();\n res.json(data);\n } catch (error) {\n console.error('Error creating guest token:', error);\n res.status(500).json({ error: 'Failed to create guest token' });\n }\n});\n\napp.listen(3001, () => {\n console.log('Server running on http://localhost:3001');\n});`;\n\n const frontendCode = `<!-- DatabrainEmbed.svelte - Svelte component -->\n<script lang=\"ts\">\n import { onMount } from 'svelte';\n import '@databrainhq/plugin';\n\n let token: string | null = null;\n\n onMount(async () => {\n try {\n const response = await fetch('/api/guest-token', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ clientId: 'your-client-id' }),\n });\n const data = await response.json();\n token = data.token;\n } catch (error) {\n console.error('Failed to fetch guest token:', error);\n }\n });\n</script>\n\n{#if !token}\n <div>Loading...</div>\n{:else}\n <${tag}\n token={token}\n ${idAttr}=\"${ctx.embedId}\"${boolAttrString}\n />\n{/if}`;\n\n const instructions = `## Svelte + Express Setup\n\n### Environment Variables\nSet the following environment variables on your backend server:\n- \\`DATABRAIN_API_TOKEN\\` - Your Databrain API token\n- \\`DATABRAIN_API_URL\\` - Your Databrain API base URL (e.g. https://app.usedatabrain.com)\n\n### Security\nThe guest token must be generated server-side. Never expose your DATABRAIN_API_TOKEN to the client.\n\n### Steps\n1. Install the plugin: \\`${installCommand}\\`\n2. Set up the Express backend (server.ts) and start it\n3. Add the DatabrainEmbed.svelte component to your Svelte app\n4. Replace 'your-client-id' with the actual client identifier for the logged-in user\n5. If using SvelteKit, you can create a server route at \\`src/routes/api/guest-token/+server.ts\\` instead of a separate Express server\n6. Proxy /api requests to the Express backend in your Vite config during development`;\n\n return {\n installCommand,\n backendCode,\n backendLanguage: 'typescript',\n frontendCode,\n frontendLanguage: 'svelte',\n instructions,\n };\n}\n","import type { TemplateContext, GeneratedCode } from './types.js';\n\nfunction kebabCase(str: string): string {\n return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();\n}\n\nfunction buildAttributes(ctx: TemplateContext) {\n const tag = ctx.embedType === 'dashboard' ? 'dbn-dashboard' : 'dbn-metric';\n const idAttr = ctx.embedType === 'dashboard' ? 'dashboard-id' : 'metric-id';\n const boolAttrs = Object.entries(ctx.options)\n .filter(([_, v]) => v === true)\n .map(([k]) => kebabCase(k))\n .join(' ');\n return { tag, idAttr, boolAttrs };\n}\n\nexport function solidjsTemplate(ctx: TemplateContext): GeneratedCode {\n const { tag, idAttr, boolAttrs } = buildAttributes(ctx);\n const boolAttrString = boolAttrs ? ` ${boolAttrs}` : '';\n\n const installCommand = 'npm install @databrainhq/plugin';\n\n const backendCode = `// server.ts - Express backend\nimport express from 'express';\nimport cors from 'cors';\n\nconst app = express();\napp.use(cors());\napp.use(express.json());\n\napp.post('/api/guest-token', async (req, res) => {\n const { clientId } = req.body;\n\n try {\n const response = await fetch(\n \\`\\${process.env.DATABRAIN_API_URL}/api/v2/guest-token/create\\`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: \\`Bearer \\${process.env.DATABRAIN_API_TOKEN}\\`,\n },\n body: JSON.stringify({ clientId }),\n }\n );\n\n const data = await response.json();\n res.json(data);\n } catch (error) {\n console.error('Error creating guest token:', error);\n res.status(500).json({ error: 'Failed to create guest token' });\n }\n});\n\napp.listen(3001, () => {\n console.log('Server running on http://localhost:3001');\n});`;\n\n const frontendCode = `// DatabrainEmbed.tsx - SolidJS component\nimport { createSignal, onMount, Show } from 'solid-js';\nimport '@databrainhq/plugin';\n\nexport default function DatabrainEmbed() {\n const [token, setToken] = createSignal<string | null>(null);\n\n onMount(async () => {\n try {\n const response = await fetch('/api/guest-token', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ clientId: 'your-client-id' }),\n });\n const data = await response.json();\n setToken(data.token);\n } catch (error) {\n console.error('Failed to fetch guest token:', error);\n }\n });\n\n return (\n <Show when={token()} fallback={<div>Loading...</div>}>\n <${tag}\n token={token()}\n ${idAttr}=\"${ctx.embedId}\"${boolAttrString}\n />\n </Show>\n );\n}`;\n\n const instructions = `## SolidJS + Express Setup\n\n### Environment Variables\nSet the following environment variables on your backend server:\n- \\`DATABRAIN_API_TOKEN\\` - Your Databrain API token\n- \\`DATABRAIN_API_URL\\` - Your Databrain API base URL (e.g. https://app.usedatabrain.com)\n\n### Security\nThe guest token must be generated server-side. Never expose your DATABRAIN_API_TOKEN to the client.\n\n### Steps\n1. Install the plugin: \\`${installCommand}\\`\n2. Set up the Express backend (server.ts) and start it\n3. Add the DatabrainEmbed component to your SolidJS app\n4. Replace 'your-client-id' with the actual client identifier for the logged-in user\n5. If using SolidStart, you can create a server function or API route instead of a separate Express server\n6. Proxy /api requests to the Express backend in your Vite config during development`;\n\n return {\n installCommand,\n backendCode,\n backendLanguage: 'typescript',\n frontendCode,\n frontendLanguage: 'tsx',\n instructions,\n };\n}\n","import type { TemplateContext, GeneratedCode } from './types.js';\n\nfunction kebabCase(str: string): string {\n return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();\n}\n\nfunction buildAttributes(ctx: TemplateContext) {\n const tag = ctx.embedType === 'dashboard' ? 'dbn-dashboard' : 'dbn-metric';\n const idAttr = ctx.embedType === 'dashboard' ? 'dashboard-id' : 'metric-id';\n const boolAttrs = Object.entries(ctx.options)\n .filter(([_, v]) => v === true)\n .map(([k]) => kebabCase(k))\n .join(' ');\n return { tag, idAttr, boolAttrs };\n}\n\nexport function vanillaTemplate(ctx: TemplateContext): GeneratedCode {\n const { tag, idAttr, boolAttrs } = buildAttributes(ctx);\n const boolAttrString = boolAttrs ? ` ${boolAttrs}` : '';\n\n const installCommand = 'npm install @databrainhq/plugin';\n\n const backendCode = `// server.ts - Express backend\nimport express from 'express';\nimport cors from 'cors';\nimport path from 'path';\n\nconst app = express();\napp.use(cors());\napp.use(express.json());\napp.use(express.static('public'));\n\napp.post('/api/guest-token', async (req, res) => {\n const { clientId } = req.body;\n\n try {\n const response = await fetch(\n \\`\\${process.env.DATABRAIN_API_URL}/api/v2/guest-token/create\\`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: \\`Bearer \\${process.env.DATABRAIN_API_TOKEN}\\`,\n },\n body: JSON.stringify({ clientId }),\n }\n );\n\n const data = await response.json();\n res.json(data);\n } catch (error) {\n console.error('Error creating guest token:', error);\n res.status(500).json({ error: 'Failed to create guest token' });\n }\n});\n\napp.listen(3001, () => {\n console.log('Server running on http://localhost:3001');\n});`;\n\n const frontendCode = `<!-- index.html - Vanilla HTML/JS -->\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Databrain Embed</title>\n <script type=\"module\">\n import '@databrainhq/plugin';\n </script>\n</head>\n<body>\n <div id=\"loading\">Loading...</div>\n <${tag}\n id=\"dbn-embed\"\n ${idAttr}=\"${ctx.embedId}\"${boolAttrString}\n style=\"display: none;\"\n ></${tag}>\n\n <script>\n async function init() {\n try {\n const response = await fetch('/api/guest-token', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ clientId: 'your-client-id' }),\n });\n const data = await response.json();\n\n const embed = document.getElementById('dbn-embed');\n embed.setAttribute('token', data.token);\n embed.style.display = '';\n document.getElementById('loading').style.display = 'none';\n } catch (error) {\n console.error('Failed to fetch guest token:', error);\n document.getElementById('loading').textContent = 'Failed to load.';\n }\n }\n\n init();\n </script>\n</body>\n</html>`;\n\n const instructions = `## Vanilla JS + Express Setup\n\n### Environment Variables\nSet the following environment variables on your backend server:\n- \\`DATABRAIN_API_TOKEN\\` - Your Databrain API token\n- \\`DATABRAIN_API_URL\\` - Your Databrain API base URL (e.g. https://app.usedatabrain.com)\n\n### Security\nThe guest token must be generated server-side. Never expose your DATABRAIN_API_TOKEN to the client.\n\n### Steps\n1. Install the plugin: \\`${installCommand}\\`\n Alternatively, you can use a CDN script tag instead of the npm import:\n \\`<script type=\"module\" src=\"https://cdn.jsdelivr.net/npm/@databrainhq/plugin\"></script>\\`\n2. Set up the Express backend (server.ts) which also serves the static HTML\n3. Place index.html in a \\`public/\\` directory\n4. Replace 'your-client-id' with the actual client identifier for the logged-in user\n5. Start the Express server and navigate to http://localhost:3001`;\n\n return {\n installCommand,\n backendCode,\n backendLanguage: 'typescript',\n frontendCode,\n frontendLanguage: 'html',\n instructions,\n };\n}\n","import type { TemplateContext, GeneratedCode } from './types.js';\nimport { reactTemplate } from './react.js';\nimport { nextjsTemplate } from './nextjs.js';\nimport { vueTemplate } from './vue.js';\nimport { angularTemplate } from './angular.js';\nimport { svelteTemplate } from './svelte.js';\nimport { solidjsTemplate } from './solidjs.js';\nimport { vanillaTemplate } from './vanilla.js';\n\ntype Framework = 'react' | 'nextjs' | 'vue' | 'angular' | 'svelte' | 'solidjs' | 'vanilla';\n\nconst templates: Record<Framework, (ctx: TemplateContext) => GeneratedCode> = {\n react: reactTemplate,\n nextjs: nextjsTemplate,\n vue: vueTemplate,\n angular: angularTemplate,\n svelte: svelteTemplate,\n solidjs: solidjsTemplate,\n vanilla: vanillaTemplate,\n};\n\nexport function getTemplate(framework: Framework, ctx: TemplateContext): GeneratedCode {\n return templates[framework](ctx);\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerListDashboards(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'list_dashboards',\n 'List dashboards by data app. Requires an API token.',\n {\n dataAppName: z.string().optional().describe('Filter by data app name'),\n },\n async (params) => {\n try {\n const query: Record<string, string> = {};\n if (params.dataAppName) query.dataAppName = params.dataAppName;\n\n const result = await client.request<unknown[]>({\n method: 'GET',\n path: '/api/v2/data-app/dashboards',\n auth: 'api',\n query: Object.keys(query).length > 0 ? query : undefined,\n cacheKey: 'list_dashboards',\n cacheTtlMs: 5 * 60 * 1000,\n });\n\n if (!Array.isArray(result) || result.length === 0) {\n return toolSuccess(\n 'No dashboards found. Create a dashboard in the Databrain UI first, then come back to embed it.'\n );\n }\n\n const formatted = result.map((d: any) =>\n `- **${d.name}** — ID: ${d._id || d.id}${d.metricCount !== undefined ? ` | ${d.metricCount} metrics` : ''}`\n ).join('\\n');\n\n return toolSuccess(`Found ${result.length} dashboard(s):\\n\\n${formatted}`);\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerListMetrics(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'list_metrics',\n 'List metrics available for embedding. Requires an API token.',\n {\n dataAppName: z.string().describe('Name of the data app'),\n clientId: z.string().optional().describe('Client ID for tenant-scoped metrics'),\n },\n async (params) => {\n try {\n const query: Record<string, string> = { dataAppName: params.dataAppName };\n if (params.clientId) query.clientId = params.clientId;\n\n const result = await client.request<unknown[]>({\n method: 'GET',\n path: '/api/v2/data-app/metrics',\n auth: 'api',\n query,\n });\n\n if (!Array.isArray(result) || result.length === 0) {\n return toolSuccess(\n 'No metrics found. Create metrics in the Databrain UI dashboard builder.'\n );\n }\n\n const formatted = result.map((m: any) =>\n `- **${m.name}** (${m.chartType || 'unknown'}) — ID: ${m._id || m.id}${m.isPublished ? ' [published]' : ''}`\n ).join('\\n');\n\n return toolSuccess(`Found ${result.length} metric(s):\\n\\n${formatted}`);\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerQueryMetricData(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'query_metric_data',\n 'Fetch data from a pre-defined metric. Requires an API token.',\n {\n embedId: z.string().describe('Embed ID'),\n metricId: z.string().describe('Metric ID to query'),\n clientId: z.string().describe('Client ID for tenant filtering'),\n filters: z.array(z.record(z.unknown())).optional().describe('Runtime filters'),\n limit: z.number().optional().describe('Row limit'),\n offset: z.number().optional().describe('Pagination offset'),\n },\n async (params) => {\n try {\n const result = await client.request<{ data?: unknown[]; columns?: unknown[]; rowCount?: number }>({\n method: 'POST',\n path: '/api/v2/data-app/query',\n body: params,\n auth: 'api',\n });\n\n const rowCount = result.rowCount ?? (Array.isArray(result.data) ? result.data.length : 0);\n let output = `Query returned ${rowCount} row(s).\\n\\n`;\n\n if (result.columns && Array.isArray(result.columns)) {\n output += `**Columns:** ${result.columns.map((c: any) => c.name || c).join(', ')}\\n\\n`;\n }\n\n if (result.data && Array.isArray(result.data)) {\n const preview = result.data.slice(0, 10);\n output += '**Data preview (first 10 rows):**\\n```json\\n' +\n JSON.stringify(preview, null, 2) +\n '\\n```';\n if (result.data.length > 10) {\n output += `\\n\\n...and ${result.data.length - 10} more rows.`;\n }\n }\n\n return toolSuccess(output);\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerGetDashboardData(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'get_dashboard_data',\n 'Fetch data for all metrics in a dashboard. Requires an API token. This is a composite operation that queries each metric.',\n {\n dashboardId: z.string().describe('Dashboard ID'),\n clientId: z.string().describe('Client ID for tenant filtering'),\n embedId: z.string().describe('Embed ID'),\n filters: z.array(z.record(z.unknown())).optional().describe('Runtime filters'),\n },\n async (params) => {\n try {\n // First get the list of metrics for this dashboard\n const metrics = await client.request<unknown[]>({\n method: 'GET',\n path: '/api/v2/data-app/metrics',\n auth: 'api',\n query: { dashboardId: params.dashboardId },\n });\n\n if (!Array.isArray(metrics) || metrics.length === 0) {\n return toolSuccess('No metrics found in this dashboard.');\n }\n\n const results: Array<{ metricId: string; metricName: string; rowCount: number }> = [];\n\n for (const metric of metrics) {\n const m = metric as any;\n try {\n const data = await client.request<{ data?: unknown[]; rowCount?: number }>({\n method: 'POST',\n path: '/api/v2/data-app/query',\n body: {\n embedId: params.embedId,\n metricId: m._id || m.id,\n clientId: params.clientId,\n filters: params.filters,\n },\n auth: 'api',\n });\n results.push({\n metricId: m._id || m.id,\n metricName: m.name || 'Unnamed',\n rowCount: data.rowCount ?? (Array.isArray(data.data) ? data.data.length : 0),\n });\n } catch {\n results.push({\n metricId: m._id || m.id,\n metricName: m.name || 'Unnamed',\n rowCount: -1,\n });\n }\n }\n\n const formatted = results.map((r) =>\n `- **${r.metricName}** (${r.metricId}): ${r.rowCount >= 0 ? `${r.rowCount} rows` : 'error fetching data'}`\n ).join('\\n');\n\n return toolSuccess(\n `Dashboard data summary (${results.length} metrics):\\n\\n${formatted}\\n\\n` +\n 'Use `query_metric_data` to fetch detailed data for individual metrics.'\n );\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerAskAiPilot(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'ask_ai_pilot',\n 'Send a natural language question to Databrain\\'s AI Pilot. Requires the embed to have AI Pilot enabled and a semantic layer configured.',\n {\n embedId: z.string().describe('Embed ID with AI Pilot enabled'),\n question: z.string().describe('Natural language question, e.g. \"What was total revenue last month?\"'),\n clientId: z.string().describe('Client ID for tenant filtering'),\n },\n async (params) => {\n try {\n const result = await client.request<{\n answer?: string;\n sql?: string;\n data?: unknown[];\n chartSuggestion?: string;\n }>({\n method: 'POST',\n path: '/api/v2/data-app/ai-pilot/ask',\n body: params,\n auth: 'api',\n });\n\n let output = '## AI Pilot Response\\n\\n';\n\n if (result.answer) {\n output += `**Answer:** ${result.answer}\\n\\n`;\n }\n\n if (result.sql) {\n output += `**SQL:**\\n\\`\\`\\`sql\\n${result.sql}\\n\\`\\`\\`\\n\\n`;\n }\n\n if (result.chartSuggestion) {\n output += `**Suggested Chart:** ${result.chartSuggestion}\\n\\n`;\n }\n\n if (result.data && Array.isArray(result.data)) {\n const preview = result.data.slice(0, 10);\n output += '**Data preview:**\\n```json\\n' +\n JSON.stringify(preview, null, 2) +\n '\\n```';\n }\n\n return toolSuccess(output);\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerDownloadMetricCsv(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'download_metric_csv',\n 'Download metric data as CSV. Returns CSV content or a download URL.',\n {\n metricId: z.string().describe('Metric ID'),\n embedId: z.string().describe('Embed ID'),\n clientId: z.string().describe('Client ID for tenant filtering'),\n filters: z.array(z.record(z.unknown())).optional().describe('Runtime filters'),\n },\n async (params) => {\n try {\n const result = await client.request<{ csv?: string; url?: string; data?: string }>({\n method: 'POST',\n path: '/api/v2/data-app/query/csv',\n body: params,\n auth: 'api',\n });\n\n if (result.url) {\n return toolSuccess(`CSV download URL:\\n\\n${result.url}\\n\\nThis link may expire — download promptly.`);\n }\n\n const csv = result.csv || result.data || '';\n if (csv) {\n const lines = csv.split('\\n');\n const preview = lines.slice(0, 20).join('\\n');\n return toolSuccess(\n `CSV data (${lines.length} lines):\\n\\n\\`\\`\\`csv\\n${preview}\\n\\`\\`\\`` +\n (lines.length > 20 ? `\\n\\n...and ${lines.length - 20} more lines.` : '')\n );\n }\n\n return toolSuccess('CSV export completed but no data was returned.');\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerListScheduledReports(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'list_scheduled_reports',\n 'List scheduled email reports for an embed.',\n {\n embedId: z.string().describe('Embed ID'),\n },\n async (params) => {\n try {\n const result = await client.request<unknown[]>({\n method: 'GET',\n path: '/api/v2/data-app/embeds/reports',\n auth: 'api',\n query: { embedId: params.embedId },\n });\n\n if (!Array.isArray(result) || result.length === 0) {\n return toolSuccess('No scheduled reports found for this embed.');\n }\n\n const formatted = result.map((r: any) =>\n `- **${r.id || r._id}** — Emails: ${r.emails?.join(', ') || 'N/A'} | Frequency: ${r.frequency || 'N/A'}${r.nextScheduledAt ? ` | Next: ${r.nextScheduledAt}` : ''}`\n ).join('\\n');\n\n return toolSuccess(`Found ${result.length} scheduled report(s):\\n\\n${formatted}`);\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerExportDashboard(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'export_dashboard',\n 'Export a dashboard as JSON. Useful for backup or migrating dashboards between environments.',\n {\n dashboardId: z.string().describe('ID of the dashboard to export'),\n },\n async (params) => {\n try {\n const result = await client.request<Record<string, unknown>>({\n method: 'POST',\n path: '/api/v2/data-app/dashboards/export',\n body: { dashboardId: params.dashboardId },\n auth: 'service',\n });\n\n return toolSuccess(\n `Dashboard exported successfully.\\n\\n` +\n '```json\\n' +\n JSON.stringify(result, null, 2) +\n '\\n```\\n\\n' +\n 'Use `import_dashboard` to import this JSON into another environment.'\n );\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\n\nexport function registerImportDashboard(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'import_dashboard',\n 'Import a dashboard from a JSON payload (previously exported via `export_dashboard`).',\n {\n dashboardJson: z.string().describe('The full dashboard JSON string from export_dashboard'),\n dataAppName: z.string().describe('Name of the target data app'),\n },\n async (params) => {\n try {\n let payload: unknown;\n try {\n payload = JSON.parse(params.dashboardJson);\n } catch {\n return toolError('Invalid JSON. Provide the exact JSON output from `export_dashboard`.');\n }\n\n const result = await client.request<{ id?: string; dashboardId?: string; error?: string }>({\n method: 'POST',\n path: '/api/v2/data-app/dashboards/import',\n body: { dashboard: payload, dataAppName: params.dataAppName },\n auth: 'service',\n invalidateCache: ['list_dashboards'],\n });\n\n if (result.error) {\n return toolError(`Import failed: ${result.error}`);\n }\n\n const id = result.dashboardId || result.id;\n return toolSuccess(\n `Dashboard imported successfully${id ? ` (ID: ${id})` : ''}.\\n\\n` +\n 'Next: Use `create_embed` to embed this dashboard.'\n );\n } catch (err) {\n if (err instanceof DatabrainApiError) return err.toToolResponse();\n return toolError(`Unexpected error: ${(err as Error).message}`);\n }\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../../client/databrain-client.js';\nimport { DatabrainApiError, toolError, toolSuccess } from '../../utils/errors.js';\nimport { logger } from '../../utils/logger.js';\n\n/**\n * Failure mapping: normalize API errors into actionable messages.\n */\nfunction mapError(err: unknown): ReturnType<typeof toolError> {\n if (err instanceof DatabrainApiError) {\n const mapped = ERROR_MAP.find((m) => m.match(err));\n if (mapped) return toolError(mapped.message(err));\n return err.toToolResponse();\n }\n const msg = (err as Error).message ?? String(err);\n if (msg.includes('ECONNREFUSED') || msg.includes('Failed to connect')) {\n return toolError('Cannot reach the Databrain API. Check that the server URL is correct and the service is running.');\n }\n return toolError(`Unexpected error: ${msg}`);\n}\n\nconst ERROR_MAP: Array<{\n match: (e: DatabrainApiError) => boolean;\n message: (e: DatabrainApiError) => string;\n}> = [\n {\n match: (e) => e.status === 404 && /dashboard/i.test(e.message),\n message: () => 'Invalid dashboard ID. Run step \"list_embeds\" again to verify available dashboards.',\n },\n {\n match: (e) => e.status === 401 && /api.token/i.test(e.message),\n message: () => 'Missing or expired API token. Re-run from step \"ensure_token\" to generate a fresh one.',\n },\n {\n match: (e) => e.status === 422,\n message: (e) => `Invalid request fields: ${e.message}. Check parameter names and types.`,\n },\n {\n match: (e) => e.status >= 500,\n message: () => 'Databrain API is temporarily unavailable. Retry in a moment.',\n },\n {\n match: (e) => e.message.includes('proxy') || e.message.includes('stale'),\n message: () => 'Stale process or proxy mismatch detected. Restart the MCP server and retry.',\n },\n];\n\nconst STEPS = ['discover', 'choose_app', 'ensure_token', 'list_embeds', 'choose_embed', 'validate', 'complete'] as const;\ntype Step = (typeof STEPS)[number];\n\nconst stateSchema = z.object({\n dataAppId: z.string().optional(),\n dataAppName: z.string().optional(),\n embedId: z.string().optional(),\n dashboardId: z.string().optional(),\n apiToken: z.string().optional(),\n clientId: z.string().optional(),\n workspaceName: z.string().optional(),\n}).describe('Accumulated setup state from previous steps');\n\nexport function registerSetupEmbedInteractive(server: McpServer, client: DatabrainClient): void {\n server.tool(\n 'setup_embed_interactive',\n `Interactive orchestrator for embedding a Databrain dashboard end-to-end.\n\nCall this tool repeatedly, advancing through steps. Each call returns either:\n- A CHOICE_REQUIRED block: present the options to the user and call again with their selection.\n- A CONFIRM_REQUIRED block: only one option was found — present it to the user and ask them to confirm before proceeding.\n- A COMPLETE block: the final result with all IDs, tokens, and an env block.\n\nSteps: discover → choose_app → ensure_token → list_embeds → choose_embed → validate → complete\n\nPass the accumulated \"state\" object back on every call so the orchestrator can track progress.`,\n {\n step: z.enum(STEPS).describe('Which step to execute'),\n state: stateSchema.optional().describe('State accumulated from previous steps — pass it back unchanged'),\n userChoice: z.string().optional().describe('User selection when a previous step returned CHOICE_REQUIRED'),\n },\n async (params) => {\n const state = params.state ?? {};\n const step = params.step;\n\n try {\n switch (step) {\n // ─── Step 1: Discover data apps ──────────────────────────\n case 'discover': {\n const apps = await client.request<any[]>({\n method: 'GET',\n path: '/api/v2/data-app/',\n auth: 'service',\n cacheKey: 'list_data_apps',\n cacheTtlMs: 10 * 60 * 1000,\n });\n\n if (!Array.isArray(apps) || apps.length === 0) {\n return toolError('No data apps found. Create one first with `create_data_app`, then re-run this tool at step \"discover\".');\n }\n\n if (apps.length === 1) {\n const app = apps[0];\n const name = app.name;\n const id = app._id || app.id;\n return toolSuccess(\n `CONFIRM_REQUIRED\\n\\n` +\n `Found one data app: **${name}** (ID: \\`${id}\\`)\\n\\n` +\n `Present this to the user and ask a simple yes/no confirmation, e.g.:\\n` +\n `\"I found one data app: **${name}**. Should I proceed with this one?\"\\n\\n` +\n `Do NOT ask the user to type the name — just wait for \"yes\", \"sure\", \"go ahead\", etc.\\n\\n` +\n `Once confirmed, call \\`setup_embed_interactive\\` with step \\`\"ensure_token\"\\` and state:\\n` +\n '```json\\n' + JSON.stringify({ ...state, dataAppName: name, dataAppId: id }, null, 2) + '\\n```'\n );\n }\n\n const options = apps.map((app: any, i: number) => {\n const id = app._id || app.id;\n return `${i + 1}. **${app.name}** — ID: \\`${id}\\`${app.workspaceName ? ` (workspace: ${app.workspaceName})` : ''}`;\n }).join('\\n');\n\n return toolSuccess(\n `CHOICE_REQUIRED\\n\\n` +\n `Found ${apps.length} data apps. Ask the user which one to use:\\n\\n${options}\\n\\n` +\n `Next: call \\`setup_embed_interactive\\` with step \\`\"choose_app\"\\` and \\`userChoice\\` set to the chosen app name.`\n );\n }\n\n // ─── Step 2: Resolve user's app choice ───────────────────\n case 'choose_app': {\n if (!params.userChoice) {\n return toolError('Missing userChoice. Ask the user which data app to use and pass the name as userChoice.');\n }\n\n const apps = await client.request<any[]>({\n method: 'GET',\n path: '/api/v2/data-app/',\n auth: 'service',\n cacheKey: 'list_data_apps',\n cacheTtlMs: 10 * 60 * 1000,\n });\n\n const choice = params.userChoice.trim().toLowerCase();\n const match = (apps || []).find((a: any) => {\n const name = (a.name || '').toLowerCase();\n const id = (a._id || a.id || '').toLowerCase();\n return name === choice || id === choice || name.includes(choice);\n });\n\n if (!match) {\n return toolError(`No data app matches \"${params.userChoice}\". Re-run step \"discover\" to see available apps.`);\n }\n\n const name = match.name;\n const id = match._id || match.id;\n return toolSuccess(\n `Selected data app: **${name}** (ID: \\`${id}\\`)\\n\\n` +\n `Next: call \\`setup_embed_interactive\\` with step \\`\"ensure_token\"\\` and state:\\n` +\n '```json\\n' + JSON.stringify({ ...state, dataAppName: name, dataAppId: id }, null, 2) + '\\n```'\n );\n }\n\n // ─── Step 3: Ensure API token is available ─────────────────\n case 'ensure_token': {\n if (!state.dataAppName) {\n return toolError('state.dataAppName is required. Run step \"discover\" first.');\n }\n\n // If an API token is already configured (env var or prior session), skip creation\n if (client.hasApiToken()) {\n return toolSuccess(\n `API token already configured — skipping creation.\\n\\n` +\n `Next: call \\`setup_embed_interactive\\` with step \\`\"list_embeds\"\\` and state:\\n` +\n '```json\\n' + JSON.stringify({ ...state, apiToken: '[CONFIGURED]' }, null, 2) + '\\n```'\n );\n }\n\n // No token available — create one\n const result = await client.request<{ key: string }>({\n method: 'POST',\n path: '/api/v2/data-app/api-tokens',\n body: { dataAppName: state.dataAppName, name: `mcp-embed-setup-${Date.now()}` },\n auth: 'service',\n });\n\n client.setRuntimeApiToken(result.key);\n\n return toolSuccess(\n `API token created for **${state.dataAppName}**.\\n\\n` +\n `**Token:** \\`${result.key}\\`\\n\\n` +\n `WARNING: This token is shown once. Store it backend-side only. Never expose it in frontend code or logs.\\n\\n` +\n `Next: call \\`setup_embed_interactive\\` with step \\`\"list_embeds\"\\` and state:\\n` +\n '```json\\n' + JSON.stringify({ ...state, apiToken: '[REDACTED — stored in session]' }, null, 2) + '\\n```'\n );\n }\n\n // ─── Step 4: List embeds ─────────────────────────────────\n case 'list_embeds': {\n const query: Record<string, string> = {};\n if (state.dataAppName) query.dataAppName = state.dataAppName;\n\n const embeds = await client.request<any[]>({\n method: 'GET',\n path: '/api/v2/data-app/embeds',\n auth: 'api',\n query: Object.keys(query).length > 0 ? query : undefined,\n cacheKey: 'list_embeds',\n cacheTtlMs: 5 * 60 * 1000,\n });\n\n if (!Array.isArray(embeds) || embeds.length === 0) {\n return toolSuccess(\n `No embeds found for data app \"${state.dataAppName}\".\\n\\n` +\n `The user needs to create an embed first using \\`create_embed\\`. ` +\n `Once created, re-run this tool at step \"list_embeds\".`\n );\n }\n\n if (embeds.length === 1) {\n const e = embeds[0];\n const embedId = e.embedId || e._id || e.id;\n const dashId = e.embedMetadata?.dashboardId || e.dashboardId;\n const name = e.name || e.externalDashboard?.name || 'Unnamed';\n return toolSuccess(\n `CONFIRM_REQUIRED\\n\\n` +\n `Found one embed: **${name}** — Embed ID: \\`${embedId}\\`${dashId ? ` | Dashboard: \\`${dashId}\\`` : ''}\\n\\n` +\n `Present this to the user and ask a simple yes/no confirmation, e.g.:\\n` +\n `\"I found one embed: **${name}**. Should I use this one?\"\\n\\n` +\n `Do NOT ask the user to type the name or ID — just wait for \"yes\", \"sure\", \"go ahead\", etc.\\n\\n` +\n `Once confirmed, call \\`setup_embed_interactive\\` with step \\`\"validate\"\\` and state:\\n` +\n '```json\\n' + JSON.stringify({ ...state, embedId, dashboardId: dashId || state.dashboardId }, null, 2) + '\\n```'\n );\n }\n\n const options = embeds.map((e: any, i: number) => {\n const embedId = e.embedId || e._id || e.id;\n const dashId = e.embedMetadata?.dashboardId || e.dashboardId;\n const name = e.name || e.externalDashboard?.name || 'Unnamed';\n return `${i + 1}. **${name}** — Embed ID: \\`${embedId}\\`${dashId ? ` | Dashboard: \\`${dashId}\\`` : ''}`;\n }).join('\\n');\n\n return toolSuccess(\n `CHOICE_REQUIRED\\n\\n` +\n `Found ${embeds.length} embed(s). Ask the user which one to use:\\n\\n${options}\\n\\n` +\n `Next: call \\`setup_embed_interactive\\` with step \\`\"choose_embed\"\\` and \\`userChoice\\` set to the embed ID or name.`\n );\n }\n\n // ─── Step 5: Resolve user's embed choice ─────────────────\n case 'choose_embed': {\n if (!params.userChoice) {\n return toolError('Missing userChoice. Ask the user which embed to use and pass the embed ID or name as userChoice.');\n }\n\n const embeds = await client.request<any[]>({\n method: 'GET',\n path: '/api/v2/data-app/embeds',\n auth: 'api',\n cacheKey: 'list_embeds',\n cacheTtlMs: 5 * 60 * 1000,\n });\n\n const choice = params.userChoice.trim().toLowerCase();\n const match = (embeds || []).find((e: any) => {\n const embedId = (e.embedId || e._id || e.id || '').toLowerCase();\n const name = (e.name || e.externalDashboard?.name || '').toLowerCase();\n return embedId === choice || name === choice || name.includes(choice) || embedId.includes(choice);\n });\n\n if (!match) {\n return toolError(`No embed matches \"${params.userChoice}\". Re-run step \"list_embeds\" to see available embeds.`);\n }\n\n const embedId = match.embedId || match._id || match.id;\n const dashId = match.embedMetadata?.dashboardId || match.dashboardId;\n const name = match.name || match.externalDashboard?.name || 'Unnamed';\n return toolSuccess(\n `Selected embed: **${name}** (Embed ID: \\`${embedId}\\`)\\n\\n` +\n `Next: call \\`setup_embed_interactive\\` with step \\`\"validate\"\\` and state:\\n` +\n '```json\\n' + JSON.stringify({ ...state, embedId, dashboardId: dashId || state.dashboardId }, null, 2) + '\\n```'\n );\n }\n\n // ─── Step 6: Validate with minimal guest token ───────────\n case 'validate': {\n if (!state.embedId) {\n return toolError('state.embedId is required. Run step \"list_embeds\" first.');\n }\n if (!state.dataAppName) {\n return toolError('state.dataAppName is required. Run step \"discover\" first.');\n }\n\n const clientId = state.clientId || 'validation-test-user';\n\n // Minimal payload — only required fields\n const body: Record<string, unknown> = {\n clientId,\n dataAppName: state.dataAppName,\n };\n\n const result = await client.request<{ token: string }>({\n method: 'POST',\n path: '/api/v2/guest-token/create',\n body,\n auth: 'api',\n });\n\n return toolSuccess(\n `Validation passed. Guest token generated successfully.\\n\\n` +\n `- clientId: \\`${clientId}\\`\\n` +\n `- dataAppName: \\`${state.dataAppName}\\`\\n` +\n `- token length: ${result.token.length} chars\\n\\n` +\n `Next: call \\`setup_embed_interactive\\` with step \\`\"complete\"\\` and state:\\n` +\n '```json\\n' + JSON.stringify({ ...state, clientId }, null, 2) + '\\n```'\n );\n }\n\n // ─── Step 7: Final deterministic output ──────────────────\n case 'complete': {\n if (!state.dataAppName || !state.embedId) {\n return toolError('Incomplete state. Ensure dataAppName and embedId are set before completing.');\n }\n\n const envBlock = [\n `DATABRAIN_DATA_APP_NAME=${state.dataAppName}`,\n `DATABRAIN_EMBED_ID=${state.embedId}`,\n state.dashboardId ? `DATABRAIN_DASHBOARD_ID=${state.dashboardId}` : null,\n state.clientId ? `DATABRAIN_CLIENT_ID=${state.clientId}` : null,\n `DATABRAIN_API_TOKEN=<paste-token-from-step-ensure_token>`,\n ].filter(Boolean).join('\\n');\n\n const result = {\n dataAppName: state.dataAppName,\n dataAppId: state.dataAppId,\n embedId: state.embedId,\n dashboardId: state.dashboardId || null,\n clientId: state.clientId || null,\n };\n\n return toolSuccess(\n `COMPLETE\\n\\n` +\n `Setup finished. Here is your embed configuration:\\n\\n` +\n '```json\\n' + JSON.stringify(result, null, 2) + '\\n```\\n\\n' +\n `**Environment variables** (add to your backend \\`.env\\`):\\n` +\n '```\\n' + envBlock + '\\n```\\n\\n' +\n `**Next steps:**\\n` +\n `1. Use \\`generate_embed_code\\` with embedId \\`${state.embedId}\\` to get frontend integration code\\n` +\n `2. Use \\`generate_guest_token\\` with real \\`clientId\\` values per end-user for multi-tenancy\\n` +\n `3. Use \\`update_embed\\` or \\`apply_embed_preset\\` to customize theme and permissions\\n\\n` +\n `WARNING: The API token from step \"create_token\" was shown once. If you lost it, rotate with \\`rotate_api_token\\`.`\n );\n }\n\n default:\n return toolError(`Unknown step \"${step}\". Valid steps: ${STEPS.join(', ')}`);\n }\n } catch (err) {\n logger.error(`[setup_embed_interactive] step=${step} error:`, err);\n return mapError(err);\n }\n },\n );\n}\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { DatabrainClient } from '../client/databrain-client.js';\n\n// Infrastructure tools\nimport { registerListDatasources } from './infrastructure/list-datasources.js';\n\n// Data App tools\nimport { registerCreateDataApp } from './data-app/create-data-app.js';\nimport { registerListDataApps } from './data-app/list-data-apps.js';\nimport { registerCreateApiToken } from './data-app/create-api-token.js';\nimport { registerListApiTokens } from './data-app/list-api-tokens.js';\nimport { registerRotateApiToken } from './data-app/rotate-api-token.js';\n\n// Datamart tools\nimport { registerListDatamarts } from './datamart/list-datamarts.js';\nimport { registerGetSemanticLayerStatus } from './datamart/get-semantic-layer-status.js';\n\n// Embed tools\nimport { registerCreateEmbed } from './embed/create-embed.js';\nimport { registerListEmbeds } from './embed/list-embeds.js';\nimport { registerGetEmbedDetails } from './embed/get-embed-details.js';\nimport { registerUpdateEmbed } from './embed/update-embed.js';\nimport { registerDeleteEmbed } from './embed/delete-embed.js';\nimport { registerRenameEmbed } from './embed/rename-embed.js';\nimport { registerApplyThemePreset } from './embed/apply-theme-preset.js';\n\n// Frontend tools\nimport { registerGenerateGuestToken } from './frontend/generate-guest-token.js';\nimport { registerGenerateEmbedCode } from './frontend/generate-embed-code.js';\n\n// Analytics tools\nimport { registerListDashboards } from './analytics/list-dashboards.js';\nimport { registerListMetrics } from './analytics/list-metrics.js';\nimport { registerQueryMetricData } from './analytics/query-metric-data.js';\nimport { registerGetDashboardData } from './analytics/get-dashboard-data.js';\nimport { registerAskAiPilot } from './analytics/ask-ai-pilot.js';\nimport { registerDownloadMetricCsv } from './analytics/download-metric-csv.js';\nimport { registerListScheduledReports } from './analytics/list-scheduled-reports.js';\nimport { registerExportDashboard } from './analytics/export-dashboard.js';\nimport { registerImportDashboard } from './analytics/import-dashboard.js';\n\n// Orchestration\nimport { registerSetupEmbedInteractive } from './orchestration/setup-embed-interactive.js';\n\nexport function registerAllTools(server: McpServer, client: DatabrainClient): void {\n // Infrastructure (read-only)\n registerListDatasources(server, client);\n\n // Data App & Tokens\n registerCreateDataApp(server, client);\n registerListDataApps(server, client);\n registerCreateApiToken(server, client);\n registerListApiTokens(server, client);\n registerRotateApiToken(server, client);\n\n // Datamart (read-only)\n registerListDatamarts(server, client);\n registerGetSemanticLayerStatus(server, client);\n\n // Embed Management\n registerCreateEmbed(server, client);\n registerListEmbeds(server, client);\n registerGetEmbedDetails(server, client);\n registerUpdateEmbed(server, client);\n registerDeleteEmbed(server, client);\n registerRenameEmbed(server, client);\n registerApplyThemePreset(server, client);\n\n // Frontend\n registerGenerateGuestToken(server, client);\n registerGenerateEmbedCode(server, client);\n\n // Analytics & Dashboards\n registerListDashboards(server, client);\n registerListMetrics(server, client);\n registerQueryMetricData(server, client);\n registerGetDashboardData(server, client);\n registerAskAiPilot(server, client);\n registerDownloadMetricCsv(server, client);\n registerListScheduledReports(server, client);\n registerExportDashboard(server, client);\n registerImportDashboard(server, client);\n\n // Orchestration\n registerSetupEmbedInteractive(server, client);\n}\n","export const gettingStartedContent = `\n# Getting Started with Databrain\n\n## Entity Model\n\nDatabrain follows a hierarchical entity model. Understanding this hierarchy is critical\nbefore performing any operations:\n\n\\`\\`\\`\nDatasource\n └── Datamart (a table or view from the datasource)\n └── Semantic Layer (business metadata on a datamart)\n\nData App (workspace container)\n ├── API Token (authenticates embed/API calls for this data app)\n ├── Dashboard (created in the Databrain UI, contains metrics)\n │ └── Metric (a chart/visualization within a dashboard)\n ├── Embed (configuration linking a dashboard to an embeddable component)\n │ └── Guest Token (short-lived token for end-user access)\n └── Datamarts (datamarts assigned to this data app)\n\\`\\`\\`\n\n### Key Relationships\n\n- A **Datasource** represents a database connection (Postgres, MySQL, BigQuery, etc.).\n- A **Datamart** is a specific table or view exposed from a datasource.\n- A **Semantic Layer** enriches a datamart with column descriptions, synonyms, and example questions for AI features.\n- A **Data App** is the top-level workspace that groups dashboards, metrics, embeds, and API tokens.\n- An **API Token** is scoped to a data app and is required to generate guest tokens.\n- A **Dashboard** is a collection of metrics, always created via the Databrain UI.\n- A **Metric** is an individual chart or visualization within a dashboard.\n- An **Embed** links a dashboard (or metric) to embeddable web component configuration.\n- A **Guest Token** is a short-lived, scoped token generated server-side for end-user access.\n\n---\n\n## Onboarding Funnel\n\nFollow these steps in order to go from zero to an embedded dashboard:\n\n### Step 1: Create a Datasource\nConnect your database by providing connection credentials (host, port, database name,\nusername, password, SSL settings). Supported databases include PostgreSQL, MySQL,\nRedshift, BigQuery, Snowflake, Databricks, ClickHouse, MongoDB, and more.\n\n### Step 2: Sync the Datasource\nAfter creating a datasource, you **must** sync it to import table and column metadata.\nThis populates the list of available datamarts.\n\n### Step 3: Create a Data App\nA data app acts as a workspace. All dashboards, metrics, embeds, and API tokens belong\nto a data app.\n\n### Step 4: Assign Datamarts to the Data App\nSelect which datamarts (tables/views) from your synced datasource should be available\nin this data app.\n\n### Step 5: Create an API Token\nGenerate an API token scoped to the data app. This token is used server-side to\ngenerate guest tokens. Never expose this token on the client side.\n\n### Step 6: Create a Dashboard (in the Databrain UI)\nDashboards cannot be created via the API. Log in to the Databrain web application,\nnavigate to your data app, and create a dashboard with the visual builder.\n\n### Step 7: Add Metrics to the Dashboard\nUse the drag-and-drop or AI-assisted metric builder inside the dashboard to create\ncharts and visualizations.\n\n### Step 8: Create an Embed Configuration\nCreate an embed config that links your dashboard to embeddable settings (theme,\naccess controls, allowed filters, etc.).\n\n### Step 9: Generate a Guest Token (Server-Side)\nOn your backend, call the guest token endpoint with the API token, embed config,\nand any tenant-specific filters. This returns a short-lived token.\n\n### Step 10: Render the Web Component\nPass the guest token to the \\`<dbn-dashboard>\\` or \\`<dbn-metric>\\` web component in\nyour frontend application.\n\n---\n\n## Quick-Start Checklist\n\nBefore you begin, ensure you have:\n\n- [ ] A **Databrain account** with access to the workspace\n- [ ] A **Service Token** (found in workspace settings; used for API calls to manage resources)\n- [ ] **Database credentials** for the datasource you want to connect (host, port, db name, user, password)\n- [ ] A frontend application where you want to embed dashboards\n\n### Service Token vs API Token\n\n| Token Type | Purpose | Scope | Where Used |\n|----------------|--------------------------------------------|---------------|--------------------|\n| Service Token | Manage resources (CRUD datasources, apps) | Workspace | Server-side API |\n| API Token | Generate guest tokens for embedding | Data App | Server-side only |\n| Guest Token | End-user access to embedded dashboards | Embed + filters| Client-side (web component) |\n\n---\n\n## Common Pitfalls\n\n### 1. Forgetting to Sync the Datasource\nCreating a datasource does **not** automatically import its tables. You must explicitly\ncall the sync endpoint (\\`POST /api/v2/datasource/sync\\`) after creation. Without syncing,\nno datamarts will be available.\n\n### 2. Not Creating an API Token Before Embed Operations\nGuest tokens require an API token scoped to the data app. If you attempt to generate\na guest token without first creating an API token, the call will fail. Always create the\nAPI token immediately after setting up the data app.\n\n### 3. Dashboards Must Be Created in the UI\nThe Databrain API does not support creating dashboards programmatically. Dashboards\nmust be created through the Databrain web application. The API can list dashboards and\ntheir metrics, but creation and design happen in the UI.\n\n### 4. Datamarts Must Be Assigned to a Data App\nEven after syncing a datasource, datamarts are not automatically available in a data app.\nYou must explicitly assign datamarts to the data app using the datamarts endpoint.\n\n### 5. Guest Tokens Are Short-Lived\nGuest tokens expire. Your backend should generate a fresh guest token for each user\nsession or implement token refresh logic. Do not cache guest tokens for extended periods.\n\n### 6. Semantic Layer Is Required for AI Features\nIf you want to use AI Pilot (natural language querying), you must generate a semantic\nlayer for your datamarts. Without it, the AI will not have enough context to generate\naccurate queries.\n\n### 7. Embed Config Must Reference an Existing Dashboard\nWhen creating an embed, the dashboard ID must reference a dashboard that already exists\nin the data app. Create the dashboard in the UI first, then create the embed config.\n`;\n","export const apiReferenceContent = `\n# Databrain API Reference\n\n## Authentication\n\nAll API requests require authentication via one of two token types passed in the\n\\`Authorization\\` header:\n\n### Service Token\n- **Purpose**: Manage workspace-level resources (datasources, data apps, datamarts, embeds).\n- **Header**: \\`Authorization: Bearer <service-token>\\`\n- **Scope**: Entire workspace. Found in workspace settings.\n- **Used for**: All CRUD operations on datasources, data apps, datamarts, embeds, and dashboards listing.\n\n### API Token\n- **Purpose**: Generate guest tokens for end-user embedding.\n- **Header**: \\`Authorization: Bearer <api-token>\\`\n- **Scope**: A single data app.\n- **Used for**: Guest token generation and metric data queries.\n\n> **Important**: Service Tokens and API Tokens are **not interchangeable**. Use the\n> correct token type for each endpoint.\n\n---\n\n## Base URL\n\nAll endpoints are relative to your Databrain instance base URL:\n\\`\\`\\`\nhttps://api.usedatabrain.com\n\\`\\`\\`\n\n---\n\n## Datasource Endpoints\n\n### Create Datasource\n\\`\\`\\`\nPOST /api/v2/datasource/\nAuthorization: Bearer <service-token>\nContent-Type: application/json\n\\`\\`\\`\n\nCreates a new database connection. Request body includes:\n- \\`name\\` (string) - Display name for the datasource\n- \\`dbName\\` (string) - Database name\n- \\`host\\` (string) - Database host\n- \\`port\\` (string) - Database port\n- \\`username\\` (string) - Database username\n- \\`password\\` (string) - Database password\n- \\`type\\` (string) - Database type (e.g., \\`POSTGRESQL\\`, \\`MYSQL\\`, \\`BIGQUERY\\`, \\`SNOWFLAKE\\`, \\`REDSHIFT\\`, \\`DATABRICKS\\`, \\`CLICKHOUSE\\`, \\`MONGODB\\`)\n- \\`isSSL\\` (boolean) - Whether to use SSL\n\nReturns the created datasource object with its \\`id\\`.\n\n### List Datasources\n\\`\\`\\`\nGET /api/v2/datasource/\nAuthorization: Bearer <service-token>\n\\`\\`\\`\n\nReturns an array of all datasources in the workspace.\n\n### Sync Datasource\n\\`\\`\\`\nPOST /api/v2/datasource/sync\nAuthorization: Bearer <service-token>\nContent-Type: application/json\n\\`\\`\\`\n\nBody: \\`{ \"datasourceId\": \"<id>\" }\\`\n\nTriggers a metadata sync that imports table and column information from the connected\ndatabase. **This must be called after creating a datasource** before datamarts become\navailable.\n\n---\n\n## Data App Endpoints\n\n### Create Data App\n\\`\\`\\`\nPOST /api/v2/data-app/\nAuthorization: Bearer <service-token>\nContent-Type: application/json\n\\`\\`\\`\n\nBody: \\`{ \"name\": \"My App\", \"description\": \"optional description\" }\\`\n\nCreates a new data app (workspace container).\n\n### List Data Apps\n\\`\\`\\`\nGET /api/v2/data-app/\nAuthorization: Bearer <service-token>\n\\`\\`\\`\n\nReturns all data apps in the workspace.\n\n---\n\n## API Token Endpoints\n\n### Create API Token\n\\`\\`\\`\nPOST /api/v2/data-app/api-tokens\nAuthorization: Bearer <service-token>\nContent-Type: application/json\n\\`\\`\\`\n\nBody: \\`{ \"dataAppId\": \"<data-app-id>\", \"name\": \"Token Name\", \"description\": \"optional\" }\\`\n\nCreates an API token scoped to the specified data app. This token is required for\ngenerating guest tokens. **Store it securely; it cannot be retrieved again after creation.**\n\n---\n\n## Datamart Endpoints\n\n### Create / Assign Datamarts\n\\`\\`\\`\nPOST /api/v2/data-app/datamarts\nAuthorization: Bearer <service-token>\nContent-Type: application/json\n\\`\\`\\`\n\nAssigns datamarts (tables/views from synced datasources) to a data app.\n\nBody: \\`{ \"dataAppId\": \"<id>\", \"datamartIds\": [\"<datamart-id-1>\", \"<datamart-id-2>\"] }\\`\n\n### List Datamarts\n\\`\\`\\`\nGET /api/v2/data-app/datamarts?dataAppId=<id>\nAuthorization: Bearer <service-token>\n\\`\\`\\`\n\nReturns all datamarts assigned to the specified data app. Also returns datamarts\navailable from synced datasources when using additional query parameters.\n\n---\n\n## Embed Endpoints\n\n### Create Embed\n\\`\\`\\`\nPOST /api/v2/data-app/embeds\nAuthorization: Bearer <service-token>\nContent-Type: application/json\n\\`\\`\\`\n\nCreates an embed configuration linking a dashboard to embeddable settings.\n\nKey body fields:\n- \\`dataAppId\\` (string) - The data app ID\n- \\`dashboardId\\` (string) - The dashboard to embed\n- \\`name\\` (string) - Embed config name\n- \\`theme\\` (object) - Optional theme configuration\n- \\`accessSettings\\` (object) - Optional access/permission settings\n\n### List Embeds\n\\`\\`\\`\nGET /api/v2/data-app/embeds?dataAppId=<id>\nAuthorization: Bearer <service-token>\n\\`\\`\\`\n\nReturns all embed configurations for a data app.\n\n### Get Embed\n\\`\\`\\`\nGET /api/v2/data-app/embeds/<embed-id>\nAuthorization: Bearer <service-token>\n\\`\\`\\`\n\nReturns a single embed configuration by ID.\n\n### Update Embed\n\\`\\`\\`\nPUT /api/v2/data-app/embeds/<embed-id>\nAuthorization: Bearer <service-token>\nContent-Type: application/json\n\\`\\`\\`\n\nUpdates an existing embed configuration (theme, access settings, etc.).\n\n---\n\n## Guest Token Endpoint\n\n### Generate Guest Token\n\\`\\`\\`\nPOST /api/v2/guest-token/create\nAuthorization: Bearer <api-token>\nContent-Type: application/json\n\\`\\`\\`\n\n**Note**: This endpoint uses an **API Token**, not a Service Token.\n\nKey body fields:\n- \\`embedId\\` (string) - The embed configuration ID\n- \\`appFilters\\` (array) - Global filters applied to all metrics\n- \\`dashboardAppFilters\\` (array) - Dashboard-specific filters\n- \\`clientId\\` (string) - Tenant identifier for multi-tenancy / row-level security\n- \\`theme\\` (object) - Runtime theme overrides\n- \\`accessSettings\\` (object) - Runtime permission overrides\n\nReturns: \\`{ \"token\": \"<guest-token>\", \"expiresAt\": \"<timestamp>\" }\\`\n\n---\n\n## Query Endpoint\n\n### Query Metric Data\n\\`\\`\\`\nPOST /api/v2/data-app/query\nAuthorization: Bearer <api-token>\nContent-Type: application/json\n\\`\\`\\`\n\nExecutes a metric query and returns data.\n\nBody:\n- \\`metricId\\` (string) - The metric to query\n- \\`filters\\` (array) - Runtime filters to apply\n- \\`limit\\` (number) - Row limit\n- \\`offset\\` (number) - Pagination offset\n\nReturns the query result data as rows and columns.\n\n---\n\n## Dashboard Endpoints\n\n### List Dashboards\n\\`\\`\\`\nGET /api/v2/data-app/dashboards?dataAppId=<id>\nAuthorization: Bearer <service-token>\n\\`\\`\\`\n\nReturns all dashboards in a data app. Note: dashboards are **created in the Databrain\nUI**, not via the API.\n\n### List Metrics\n\\`\\`\\`\nGET /api/v2/data-app/metrics?dashboardId=<id>\nAuthorization: Bearer <service-token>\n\\`\\`\\`\n\nReturns all metrics within a dashboard.\n\n---\n\n## Error Handling\n\nAll endpoints return standard HTTP status codes:\n- \\`200\\` - Success\n- \\`201\\` - Created\n- \\`400\\` - Bad request (missing or invalid parameters)\n- \\`401\\` - Unauthorized (invalid or missing token)\n- \\`403\\` - Forbidden (token does not have required scope)\n- \\`404\\` - Resource not found\n- \\`500\\` - Internal server error\n\nError responses include a JSON body:\n\\`\\`\\`json\n{\n \"error\": \"Error message describing the issue\"\n}\n\\`\\`\\`\n\n---\n\n## Rate Limits\n\nAPI calls are subject to rate limiting. If you receive a \\`429\\` status code, back off\nand retry after the duration indicated in the \\`Retry-After\\` header.\n`;\n","export const embeddingGuideContent = `\n# Databrain Embedding Guide\n\n## Overview\n\nDatabrain provides embeddable analytics through **web components**. These are framework-\nagnostic custom HTML elements that render dashboards and individual metrics inside your\napplication.\n\nTwo primary components are available:\n- \\`<dbn-dashboard>\\` - Embeds a full dashboard with all its metrics\n- \\`<dbn-metric>\\` - Embeds a single metric/chart\n\nThe embedding flow follows three steps:\n1. **Create an embed configuration** (server-side, one-time setup)\n2. **Generate a guest token** (server-side, per user session)\n3. **Render the web component** (client-side, in your frontend)\n\n---\n\n## Installation\n\nInstall the Databrain plugin package:\n\n\\`\\`\\`bash\nnpm install @databrainhq/plugin\n\\`\\`\\`\n\nOr with yarn:\n\\`\\`\\`bash\nyarn add @databrainhq/plugin\n\\`\\`\\`\n\nOr with pnpm:\n\\`\\`\\`bash\npnpm add @databrainhq/plugin\n\\`\\`\\`\n\nAfter installation, import the package in your application entry point to register the\nweb components:\n\n\\`\\`\\`typescript\nimport '@databrainhq/plugin';\n\\`\\`\\`\n\nThis registers the \\`<dbn-dashboard>\\` and \\`<dbn-metric>\\` custom elements globally.\n\n---\n\n## Step-by-Step Embedding Flow\n\n### Step 1: Create an Embed Configuration\n\nUsing the Databrain API (or the MCP tools), create an embed configuration that links\na dashboard to your embedding preferences:\n\n\\`\\`\\`json\n{\n \"dataAppId\": \"your-data-app-id\",\n \"dashboardId\": \"your-dashboard-id\",\n \"name\": \"Customer Analytics Embed\",\n \"theme\": { },\n \"accessSettings\": { }\n}\n\\`\\`\\`\n\nThis returns an \\`embedId\\` that you will use when generating guest tokens.\n\n### Step 2: Generate a Guest Token (Server-Side)\n\nOn your backend server, call the guest token endpoint. **Never generate guest tokens\non the client side**, as this would expose your API token.\n\n\\`\\`\\`typescript\n// Server-side code (e.g., Express.js route handler)\nconst response = await fetch('https://api.usedatabrain.com/api/v2/guest-token/create', {\n method: 'POST',\n headers: {\n 'Authorization': \\`Bearer \\${apiToken}\\`, // API Token, NOT Service Token\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n embedId: 'your-embed-id',\n clientId: 'tenant-123', // For multi-tenancy\n appFilters: [], // Global filters\n dashboardAppFilters: [], // Dashboard-specific filters\n }),\n});\n\nconst { token } = await response.json();\n// Return this token to the frontend\n\\`\\`\\`\n\n### Step 3: Add the Web Component (Client-Side)\n\nPass the guest token to the web component in your HTML:\n\n\\`\\`\\`html\n<dbn-dashboard\n token=\"<guest-token>\"\n dashboard-id=\"<dashboard-id>\"\n></dbn-dashboard>\n\\`\\`\\`\n\nOr for a single metric:\n\n\\`\\`\\`html\n<dbn-metric\n token=\"<guest-token>\"\n metric-id=\"<metric-id>\"\n></dbn-metric>\n\\`\\`\\`\n\n---\n\n## Framework Integration Notes\n\n### React\n\n\\`\\`\\`tsx\nimport '@databrainhq/plugin';\nimport { useEffect, useState } from 'react';\n\nfunction Dashboard() {\n const [token, setToken] = useState<string>('');\n\n useEffect(() => {\n fetch('/api/guest-token')\n .then(res => res.json())\n .then(data => setToken(data.token));\n }, []);\n\n if (!token) return <div>Loading...</div>;\n\n return (\n <dbn-dashboard\n token={token}\n dashboard-id=\"your-dashboard-id\"\n />\n );\n}\n\\`\\`\\`\n\nYou may need to add type declarations for the custom elements:\n\n\\`\\`\\`typescript\n// src/types/dbn.d.ts\ndeclare namespace JSX {\n interface IntrinsicElements {\n 'dbn-dashboard': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {\n token?: string;\n 'dashboard-id'?: string;\n };\n 'dbn-metric': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {\n token?: string;\n 'metric-id'?: string;\n };\n }\n}\n\\`\\`\\`\n\n### Next.js\n\nUse dynamic imports to avoid SSR issues since web components require the DOM:\n\n\\`\\`\\`tsx\n'use client';\n\nimport dynamic from 'next/dynamic';\n\nconst DashboardEmbed = dynamic(() => {\n import('@databrainhq/plugin');\n return Promise.resolve(({ token, dashboardId }: { token: string; dashboardId: string }) => (\n <dbn-dashboard token={token} dashboard-id={dashboardId} />\n ));\n}, { ssr: false });\n\\`\\`\\`\n\n### Vue\n\n\\`\\`\\`vue\n<template>\n <dbn-dashboard\n v-if=\"token\"\n :token=\"token\"\n :dashboard-id=\"dashboardId\"\n />\n</template>\n\n<script setup>\nimport '@databrainhq/plugin';\nimport { ref, onMounted } from 'vue';\n\nconst token = ref('');\nconst dashboardId = 'your-dashboard-id';\n\nonMounted(async () => {\n const res = await fetch('/api/guest-token');\n const data = await res.json();\n token.value = data.token;\n});\n</script>\n\\`\\`\\`\n\nConfigure Vue to recognize custom elements:\n\n\\`\\`\\`typescript\n// vite.config.ts\nexport default defineConfig({\n plugins: [\n vue({\n template: {\n compilerOptions: {\n isCustomElement: (tag) => tag.startsWith('dbn-'),\n },\n },\n }),\n ],\n});\n\\`\\`\\`\n\n### Angular\n\nAdd \\`CUSTOM_ELEMENTS_SCHEMA\\` to your module:\n\n\\`\\`\\`typescript\nimport { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';\nimport '@databrainhq/plugin';\n\n@NgModule({\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\n})\nexport class AppModule {}\n\\`\\`\\`\n\nThen use in templates:\n\n\\`\\`\\`html\n<dbn-dashboard\n [attr.token]=\"guestToken\"\n [attr.dashboard-id]=\"dashboardId\"\n></dbn-dashboard>\n\\`\\`\\`\n\n### Svelte\n\n\\`\\`\\`svelte\n<script>\n import '@databrainhq/plugin';\n import { onMount } from 'svelte';\n\n let token = '';\n const dashboardId = 'your-dashboard-id';\n\n onMount(async () => {\n const res = await fetch('/api/guest-token');\n const data = await res.json();\n token = data.token;\n });\n</script>\n\n{#if token}\n <dbn-dashboard {token} dashboard-id={dashboardId} />\n{/if}\n\\`\\`\\`\n\n### SolidJS\n\n\\`\\`\\`tsx\nimport '@databrainhq/plugin';\nimport { createResource } from 'solid-js';\n\nfunction Dashboard() {\n const [token] = createResource(async () => {\n const res = await fetch('/api/guest-token');\n const data = await res.json();\n return data.token;\n });\n\n return (\n <Show when={token()}>\n <dbn-dashboard token={token()} dashboard-id=\"your-dashboard-id\" />\n </Show>\n );\n}\n\\`\\`\\`\n\n### Vanilla JavaScript\n\n\\`\\`\\`html\n<script type=\"module\">\n import '@databrainhq/plugin';\n</script>\n\n<dbn-dashboard id=\"dashboard\"></dbn-dashboard>\n\n<script>\n fetch('/api/guest-token')\n .then(res => res.json())\n .then(data => {\n const el = document.getElementById('dashboard');\n el.setAttribute('token', data.token);\n el.setAttribute('dashboard-id', 'your-dashboard-id');\n });\n</script>\n\\`\\`\\`\n\n---\n\n## Security Best Practices\n\n### Never Expose the API Token Client-Side\nThe API token has broad permissions for the data app. It must only be used on your\nbackend server. Exposing it in frontend code, environment variables accessible to\nthe browser, or client-side bundles is a security risk.\n\n### Always Generate Guest Tokens Server-Side\nGuest tokens should be generated by your backend and passed to the frontend. This\nensures that your API token stays secret and that you can apply tenant-specific\nfilters and permissions.\n\n### Use Short-Lived Guest Tokens\nGuest tokens have an expiration time. Generate fresh tokens for each user session.\nImplement token refresh logic if sessions are long-lived.\n\n### Apply Tenant Filters via Guest Tokens\nFor multi-tenant applications, always pass \\`clientId\\` and appropriate \\`appFilters\\`\nwhen generating the guest token. This ensures row-level security is enforced\nserver-side and cannot be bypassed by the end user.\n\n### Validate User Identity Before Token Generation\nBefore generating a guest token, verify the requesting user's identity and\nauthorization in your application. Only generate tokens with the appropriate\nscope and filters for that user.\n`;\n","export const filterReferenceContent = `\n# Databrain Filter Reference\n\n## Overview\n\nFilters in Databrain allow you to restrict and scope the data displayed in dashboards\nand metrics. Filters can be applied at multiple levels: via guest tokens (server-side),\nvia the query API (runtime), or via dashboard-level configuration in the UI.\n\n---\n\n## Filter Types\n\n### String Filters\n\nString filters operate on text/varchar columns.\n\n| Operator | Description | Example Value |\n|------------|------------------------------------|--------------------------|\n| \\`=\\` | Exact match | \\`\"active\"\\` |\n| \\`IN\\` | Matches any value in a list | \\`[\"active\", \"pending\"]\\` |\n| \\`NOT IN\\` | Excludes values in a list | \\`[\"deleted\", \"archived\"]\\`|\n| \\`LIKE\\` | Pattern match (use % as wildcard) | \\`\"%corp%\"\\` |\n\n**JSON Examples:**\n\n\\`\\`\\`json\n{\n \"columnName\": \"status\",\n \"tableName\": \"orders\",\n \"operator\": \"=\",\n \"value\": \"active\",\n \"type\": \"string\"\n}\n\\`\\`\\`\n\n\\`\\`\\`json\n{\n \"columnName\": \"region\",\n \"tableName\": \"customers\",\n \"operator\": \"IN\",\n \"value\": [\"US\", \"CA\", \"UK\"],\n \"type\": \"string\"\n}\n\\`\\`\\`\n\n\\`\\`\\`json\n{\n \"columnName\": \"company_name\",\n \"tableName\": \"accounts\",\n \"operator\": \"LIKE\",\n \"value\": \"%technologies%\",\n \"type\": \"string\"\n}\n\\`\\`\\`\n\n### Number Filters\n\nNumber filters operate on numeric columns (integer, float, decimal).\n\n| Operator | Description | Example Value |\n|-------------|-------------------------|-----------------|\n| \\`=\\` | Equal to | \\`100\\` |\n| \\`<\\` | Less than | \\`50\\` |\n| \\`>\\` | Greater than | \\`1000\\` |\n| \\`<=\\` | Less than or equal | \\`99\\` |\n| \\`>=\\` | Greater than or equal | \\`10\\` |\n| \\`<>\\` | Not equal to | \\`0\\` |\n| \\`BETWEEN\\` | Within a range (inclusive)| \\`[10, 100]\\` |\n\n**JSON Examples:**\n\n\\`\\`\\`json\n{\n \"columnName\": \"amount\",\n \"tableName\": \"transactions\",\n \"operator\": \">=\",\n \"value\": 1000,\n \"type\": \"number\"\n}\n\\`\\`\\`\n\n\\`\\`\\`json\n{\n \"columnName\": \"quantity\",\n \"tableName\": \"order_items\",\n \"operator\": \"BETWEEN\",\n \"value\": [1, 100],\n \"type\": \"number\"\n}\n\\`\\`\\`\n\n### Null Filters\n\nNull filters check for the presence or absence of values.\n\n| Operator | Description |\n|----------------|--------------------------------|\n| \\`IS NULL\\` | Column value is null/missing |\n| \\`IS NOT NULL\\` | Column value exists |\n\n**JSON Examples:**\n\n\\`\\`\\`json\n{\n \"columnName\": \"deleted_at\",\n \"tableName\": \"users\",\n \"operator\": \"IS NULL\",\n \"type\": \"null\"\n}\n\\`\\`\\`\n\n\\`\\`\\`json\n{\n \"columnName\": \"email\",\n \"tableName\": \"contacts\",\n \"operator\": \"IS NOT NULL\",\n \"type\": \"null\"\n}\n\\`\\`\\`\n\n---\n\n## Filter Application Methods\n\n### 1. Guest Token Filters (Server-Side)\n\nFilters applied via the guest token are enforced server-side and **cannot be removed\nor modified by end users**. This is the most secure way to apply filters, especially\nfor multi-tenancy.\n\n#### appFilters (Global Filters)\n\nApplied to **all metrics** across all dashboards in the embed:\n\n\\`\\`\\`json\n{\n \"embedId\": \"embed-123\",\n \"appFilters\": [\n {\n \"columnName\": \"organization_id\",\n \"tableName\": \"events\",\n \"operator\": \"=\",\n \"value\": \"org-456\",\n \"type\": \"string\"\n },\n {\n \"columnName\": \"is_active\",\n \"tableName\": \"events\",\n \"operator\": \"=\",\n \"value\": 1,\n \"type\": \"number\"\n }\n ]\n}\n\\`\\`\\`\n\n#### dashboardAppFilters (Dashboard-Specific Filters)\n\nApplied to specific dashboards. Useful when an embed includes multiple dashboards\nand you want different filters per dashboard:\n\n\\`\\`\\`json\n{\n \"embedId\": \"embed-123\",\n \"dashboardAppFilters\": [\n {\n \"dashboardId\": \"dashboard-abc\",\n \"filters\": [\n {\n \"columnName\": \"department\",\n \"tableName\": \"employees\",\n \"operator\": \"IN\",\n \"value\": [\"engineering\", \"product\"],\n \"type\": \"string\"\n }\n ]\n },\n {\n \"dashboardId\": \"dashboard-xyz\",\n \"filters\": [\n {\n \"columnName\": \"region\",\n \"tableName\": \"sales\",\n \"operator\": \"=\",\n \"value\": \"APAC\",\n \"type\": \"string\"\n }\n ]\n }\n ]\n}\n\\`\\`\\`\n\n### 2. Runtime Filters via API\n\nWhen querying metric data directly via the API, you can pass runtime filters:\n\n\\`\\`\\`json\n{\n \"metricId\": \"metric-789\",\n \"filters\": [\n {\n \"columnName\": \"created_at\",\n \"tableName\": \"orders\",\n \"operator\": \">=\",\n \"value\": \"2024-01-01\",\n \"type\": \"string\"\n }\n ],\n \"limit\": 100\n}\n\\`\\`\\`\n\n### 3. Dashboard-Level Filters (UI)\n\nFilters can also be configured in the Databrain dashboard UI. These allow end users\nto interactively filter data using dropdowns, date pickers, and search inputs. The\navailable filter columns and behavior are configured when building the dashboard.\n\nDashboard-level filters can be combined with guest token filters. Guest token filters\nalways take precedence and cannot be overridden by UI filters.\n\n---\n\n## Filter Combination Rules\n\n- Multiple filters are combined with **AND** logic.\n- Filters from different levels stack: guest token filters AND dashboard filters AND\n runtime filters all apply simultaneously.\n- Guest token filters cannot be overridden or removed by the end user.\n- If the same column is filtered at multiple levels, all conditions must be satisfied.\n\n---\n\n## Filter Format Summary\n\nEvery filter object follows this structure:\n\n\\`\\`\\`json\n{\n \"columnName\": \"string - the column name in the database table\",\n \"tableName\": \"string - the table name (must match a datamart table)\",\n \"operator\": \"string - the comparison operator\",\n \"value\": \"string | number | array - the filter value(s)\",\n \"type\": \"string - one of: string, number, null\"\n}\n\\`\\`\\`\n\n### Notes\n\n- \\`tableName\\` must reference a table that exists as a datamart in the data app.\n- \\`columnName\\` must be a valid column in that table.\n- For \\`IN\\` and \\`NOT IN\\` operators, \\`value\\` must be an array.\n- For \\`BETWEEN\\`, \\`value\\` must be a two-element array \\`[min, max]\\`.\n- For \\`IS NULL\\` and \\`IS NOT NULL\\`, the \\`value\\` field is ignored (can be omitted or null).\n- Date filtering is typically done using string comparisons with ISO format dates.\n`;\n","export const themeReferenceContent = `\n# Databrain Theme Reference\n\n## Overview\n\nThemes control the visual appearance of embedded dashboards and metrics. Databrain\nsupports predefined themes and fully custom theme configurations. Themes can be applied\nat multiple levels: embed configuration, guest token, or web component attributes.\n\n---\n\n## Theme Categories\n\nThemes are organized into categories, each controlling a specific visual area:\n\n### general\nTop-level appearance settings that apply globally.\n\n| Property | Type | Description |\n|-------------------|---------|------------------------------------------|\n| \\`fontFamily\\` | string | Primary font family |\n| \\`backgroundColor\\` | string | Overall background color |\n| \\`primaryColor\\` | string | Primary accent color |\n| \\`secondaryColor\\` | string | Secondary accent color |\n| \\`textColor\\` | string | Default text color |\n| \\`borderColor\\` | string | Default border color |\n| \\`borderRadius\\` | string | Default border radius (e.g., \"8px\") |\n\n### dashboard\nDashboard container and layout styling.\n\n| Property | Type | Description |\n|-----------------------|---------|--------------------------------------|\n| \\`backgroundColor\\` | string | Dashboard background color |\n| \\`padding\\` | string | Dashboard padding |\n| \\`gap\\` | string | Gap between metric cards |\n| \\`gridCols\\` | number | Number of grid columns |\n| \\`filterBarBackground\\`| string | Filter bar background color |\n\n### chart\nDefault chart appearance settings.\n\n| Property | Type | Description |\n|----------------------|----------|--------------------------------------|\n| \\`colorPalette\\` | string[] | Array of colors for chart series |\n| \\`backgroundColor\\` | string | Chart area background color |\n| \\`axisColor\\` | string | Axis line color |\n| \\`axisLabelColor\\` | string | Axis label text color |\n| \\`gridColor\\` | string | Grid line color |\n| \\`tooltipBackground\\` | string | Tooltip background color |\n| \\`tooltipTextColor\\` | string | Tooltip text color |\n| \\`legendColor\\` | string | Legend text color |\n\n### cardTitle\nMetric card title styling.\n\n| Property | Type | Description |\n|----------------|---------|------------------------------------------|\n| \\`fontSize\\` | string | Title font size (e.g., \"16px\") |\n| \\`fontWeight\\` | string | Title font weight (e.g., \"600\") |\n| \\`color\\` | string | Title text color |\n| \\`fontFamily\\` | string | Title font family override |\n\n### cardDescription\nMetric card description styling.\n\n| Property | Type | Description |\n|----------------|---------|------------------------------------------|\n| \\`fontSize\\` | string | Description font size |\n| \\`fontWeight\\` | string | Description font weight |\n| \\`color\\` | string | Description text color |\n| \\`fontFamily\\` | string | Description font family override |\n\n### cardCustomization\nMetric card container styling.\n\n| Property | Type | Description |\n|--------------------|---------|--------------------------------------|\n| \\`backgroundColor\\` | string | Card background color |\n| \\`borderColor\\` | string | Card border color |\n| \\`borderWidth\\` | string | Card border width |\n| \\`borderRadius\\` | string | Card border radius |\n| \\`padding\\` | string | Card internal padding |\n| \\`shadow\\` | string | Card box shadow |\n\n### chartCustomization\nFine-grained chart element styling.\n\n| Property | Type | Description |\n|------------------------|---------|------------------------------------|\n| \\`barBorderRadius\\` | string | Border radius for bar charts |\n| \\`barWidth\\` | string | Bar width in bar charts |\n| \\`lineWidth\\` | string | Line width in line charts |\n| \\`pointSize\\` | string | Data point size in line/scatter |\n| \\`areaOpacity\\` | string | Area fill opacity (0-1) |\n| \\`pieBorderWidth\\` | string | Border width for pie chart slices |\n| \\`doughnutCutout\\` | string | Cutout percentage for doughnut |\n\n---\n\n## Predefined Themes\n\nDatabrain offers predefined themes that can be referenced by name:\n\n- **light** - Clean light theme with white backgrounds\n- **dark** - Dark theme with dark backgrounds and light text\n- **modern** - Contemporary styling with subtle shadows and rounded corners\n- **minimal** - Minimalist design with reduced visual elements\n- **corporate** - Professional styling suited for business dashboards\n\nTo use a predefined theme, reference it by name in the embed or guest token configuration.\n\n---\n\n## Custom Theme JSON Structure\n\nA full custom theme object:\n\n\\`\\`\\`json\n{\n \"general\": {\n \"fontFamily\": \"Inter, sans-serif\",\n \"backgroundColor\": \"#ffffff\",\n \"primaryColor\": \"#4F46E5\",\n \"secondaryColor\": \"#10B981\",\n \"textColor\": \"#1F2937\",\n \"borderColor\": \"#E5E7EB\",\n \"borderRadius\": \"8px\"\n },\n \"dashboard\": {\n \"backgroundColor\": \"#F9FAFB\",\n \"padding\": \"24px\",\n \"gap\": \"16px\",\n \"filterBarBackground\": \"#FFFFFF\"\n },\n \"chart\": {\n \"colorPalette\": [\"#4F46E5\", \"#10B981\", \"#F59E0B\", \"#EF4444\", \"#8B5CF6\", \"#06B6D4\"],\n \"backgroundColor\": \"transparent\",\n \"axisColor\": \"#9CA3AF\",\n \"axisLabelColor\": \"#6B7280\",\n \"gridColor\": \"#F3F4F6\",\n \"tooltipBackground\": \"#1F2937\",\n \"tooltipTextColor\": \"#FFFFFF\",\n \"legendColor\": \"#374151\"\n },\n \"cardTitle\": {\n \"fontSize\": \"16px\",\n \"fontWeight\": \"600\",\n \"color\": \"#111827\",\n \"fontFamily\": \"Inter, sans-serif\"\n },\n \"cardDescription\": {\n \"fontSize\": \"13px\",\n \"fontWeight\": \"400\",\n \"color\": \"#6B7280\",\n \"fontFamily\": \"Inter, sans-serif\"\n },\n \"cardCustomization\": {\n \"backgroundColor\": \"#FFFFFF\",\n \"borderColor\": \"#E5E7EB\",\n \"borderWidth\": \"1px\",\n \"borderRadius\": \"12px\",\n \"padding\": \"20px\",\n \"shadow\": \"0 1px 3px rgba(0,0,0,0.1)\"\n },\n \"chartCustomization\": {\n \"barBorderRadius\": \"4px\",\n \"lineWidth\": \"2px\",\n \"pointSize\": \"4px\",\n \"areaOpacity\": \"0.1\"\n }\n}\n\\`\\`\\`\n\nYou do not need to specify all properties. Any omitted properties will use the\ndefaults from the active base theme.\n\n---\n\n## How to Apply Themes\n\n### Via Embed Configuration\n\nSet the theme when creating or updating an embed:\n\n\\`\\`\\`json\n{\n \"dataAppId\": \"app-123\",\n \"dashboardId\": \"dash-456\",\n \"name\": \"Themed Embed\",\n \"theme\": {\n \"general\": {\n \"primaryColor\": \"#4F46E5\",\n \"fontFamily\": \"Inter, sans-serif\"\n },\n \"chart\": {\n \"colorPalette\": [\"#4F46E5\", \"#10B981\", \"#F59E0B\"]\n }\n }\n}\n\\`\\`\\`\n\n### Via Guest Token (Runtime Override)\n\nApply or override theme settings at guest token generation time:\n\n\\`\\`\\`json\n{\n \"embedId\": \"embed-789\",\n \"theme\": {\n \"general\": {\n \"primaryColor\": \"#DC2626\"\n },\n \"dashboard\": {\n \"backgroundColor\": \"#FEF2F2\"\n }\n }\n}\n\\`\\`\\`\n\nGuest token theme settings override embed-level theme settings.\n\n### Via Web Component Attribute\n\nPass a theme JSON string as an attribute on the web component:\n\n\\`\\`\\`html\n<dbn-dashboard\n token=\"guest-token\"\n dashboard-id=\"dash-456\"\n options='{\"theme\": {\"general\": {\"primaryColor\": \"#4F46E5\"}}}'\n></dbn-dashboard>\n\\`\\`\\`\n\n### Theme Precedence (Highest to Lowest)\n\n1. Web component attribute theme\n2. Guest token theme\n3. Embed configuration theme\n4. Predefined/default theme\n`;\n","export const webComponentReferenceContent = `\n# Databrain Web Component Reference\n\n## Overview\n\nDatabrain provides two web components for embedding analytics into any web application:\n\n- \\`<dbn-dashboard>\\` - Renders a full dashboard with all its metrics\n- \\`<dbn-metric>\\` - Renders a single metric/chart\n\nBoth are standard web components (custom HTML elements) and work in any framework\nor vanilla HTML/JavaScript.\n\n---\n\n## Installation\n\n\\`\\`\\`bash\nnpm install @databrainhq/plugin\n\\`\\`\\`\n\nImport in your application entry point:\n\n\\`\\`\\`typescript\nimport '@databrainhq/plugin';\n\\`\\`\\`\n\n---\n\n## \\`<dbn-dashboard>\\`\n\nEmbeds a complete dashboard including all its metrics, filters, and layout.\n\n### Required Attributes\n\n| Attribute | Type | Description |\n|------------------|--------|--------------------------------------------|\n| \\`token\\` | string | Guest token generated server-side |\n| \\`dashboard-id\\` | string | ID of the dashboard to render |\n\n### Basic Usage\n\n\\`\\`\\`html\n<dbn-dashboard\n token=\"eyJhbGciOi...\"\n dashboard-id=\"dash-abc-123\"\n></dbn-dashboard>\n\\`\\`\\`\n\n---\n\n## \\`<dbn-metric>\\`\n\nEmbeds a single metric/chart from a dashboard.\n\n### Required Attributes\n\n| Attribute | Type | Description |\n|----------------|--------|--------------------------------------------|\n| \\`token\\` | string | Guest token generated server-side |\n| \\`metric-id\\` | string | ID of the metric to render |\n\n### Basic Usage\n\n\\`\\`\\`html\n<dbn-metric\n token=\"eyJhbGciOi...\"\n metric-id=\"metric-xyz-456\"\n></dbn-metric>\n\\`\\`\\`\n\n---\n\n## Display Control Attributes\n\nThese boolean attributes control the visibility of UI elements within the embedded\ncomponents.\n\n| Attribute | Component | Description |\n|--------------------------------|-------------|------------------------------------------------|\n| \\`is-hide-table-preview\\` | both | Hides the table/data preview toggle |\n| \\`is-hide-chart-settings\\` | both | Hides the chart settings/configuration panel |\n| \\`disable-fullscreen\\` | both | Disables the fullscreen toggle button |\n\n### Example\n\n\\`\\`\\`html\n<dbn-dashboard\n token=\"eyJhbGciOi...\"\n dashboard-id=\"dash-abc-123\"\n is-hide-table-preview\n is-hide-chart-settings\n disable-fullscreen\n></dbn-dashboard>\n\\`\\`\\`\n\n---\n\n## Download and Export Attributes\n\nControl data export capabilities for end users.\n\n| Attribute | Component | Description |\n|--------------------------------|-------------|--------------------------------------------------|\n| \\`enable-download-csv\\` | both | Enables CSV download for individual metrics |\n| \\`enable-email-csv\\` | both | Enables emailing metric data as CSV |\n| \\`enable-download-all-metrics\\` | dashboard | Enables bulk download of all metrics as CSV |\n| \\`enable-download-all-pdf\\` | dashboard | Enables downloading entire dashboard as PDF |\n\n### Example\n\n\\`\\`\\`html\n<dbn-dashboard\n token=\"eyJhbGciOi...\"\n dashboard-id=\"dash-abc-123\"\n enable-download-csv\n enable-email-csv\n enable-download-all-metrics\n enable-download-all-pdf\n></dbn-dashboard>\n\\`\\`\\`\n\n---\n\n## Advanced Attributes\n\n| Attribute | Component | Description |\n|----------------------------------|-------------|------------------------------------------------------|\n| \\`enable-multi-metric-filters\\` | dashboard | Enables cross-metric filter interactions |\n| \\`is-sticky-dashboard-filters\\` | dashboard | Makes the filter bar sticky at the top on scroll |\n| \\`options-icon\\` | both | Custom icon for the options/settings menu button |\n\n### Example\n\n\\`\\`\\`html\n<dbn-dashboard\n token=\"eyJhbGciOi...\"\n dashboard-id=\"dash-abc-123\"\n enable-multi-metric-filters\n is-sticky-dashboard-filters\n></dbn-dashboard>\n\\`\\`\\`\n\n---\n\n## The \\`options\\` Attribute\n\nThe \\`options\\` attribute accepts a JSON string with advanced configuration:\n\n\\`\\`\\`html\n<dbn-dashboard\n token=\"eyJhbGciOi...\"\n dashboard-id=\"dash-abc-123\"\n options='{ \"theme\": {...}, \"accessSettings\": {...}, \"customMessages\": {...} }'\n></dbn-dashboard>\n\\`\\`\\`\n\n### Options JSON Structure\n\n\\`\\`\\`json\n{\n \"theme\": {\n \"general\": { },\n \"chart\": { },\n \"dashboard\": { },\n \"cardTitle\": { },\n \"cardDescription\": { },\n \"cardCustomization\": { },\n \"chartCustomization\": { }\n },\n \"accessSettings\": {\n \"isAllowMetricCreation\": false,\n \"isAllowMetricDeletion\": false,\n \"isAllowMetricEditing\": false,\n \"isAllowChangeLayout\": false,\n \"isAllowDrillDown\": true,\n \"isAllowAiPilot\": false\n },\n \"customMessages\": {\n \"noDataMessage\": \"No data available for the selected filters.\",\n \"errorMessage\": \"Something went wrong. Please try again.\"\n }\n}\n\\`\\`\\`\n\n### Setting Options in JavaScript\n\nFor dynamic configurations, set the \\`options\\` attribute via JavaScript:\n\n\\`\\`\\`javascript\nconst dashboard = document.querySelector('dbn-dashboard');\ndashboard.setAttribute('options', JSON.stringify({\n theme: {\n general: { primaryColor: '#4F46E5' }\n },\n accessSettings: {\n isAllowDrillDown: true,\n isAllowAiPilot: true\n }\n}));\n\\`\\`\\`\n\n---\n\n## Boolean Attribute Convention\n\nDatabrain web components follow the standard HTML boolean attribute convention:\n\n- **Presence** of the attribute means \\`true\\`\n- **Absence** of the attribute means \\`false\\`\n\n\\`\\`\\`html\n<!-- Downloads enabled -->\n<dbn-dashboard token=\"...\" dashboard-id=\"...\" enable-download-csv></dbn-dashboard>\n\n<!-- Downloads disabled (attribute omitted) -->\n<dbn-dashboard token=\"...\" dashboard-id=\"...\"></dbn-dashboard>\n\\`\\`\\`\n\nThe value of a boolean attribute does not matter. These are all equivalent:\n\\`\\`\\`html\n<dbn-dashboard enable-download-csv></dbn-dashboard>\n<dbn-dashboard enable-download-csv=\"\"></dbn-dashboard>\n<dbn-dashboard enable-download-csv=\"true\"></dbn-dashboard>\n\\`\\`\\`\n\nTo disable a boolean attribute, remove it entirely from the element. Setting it to\n\\`\"false\"\\` does **not** disable it (the attribute is still present).\n\n---\n\n## Responsive Behavior\n\nBoth components are responsive and adapt to their container size. Ensure the parent\ncontainer has defined dimensions:\n\n\\`\\`\\`html\n<div style=\"width: 100%; height: 600px;\">\n <dbn-dashboard token=\"...\" dashboard-id=\"...\"></dbn-dashboard>\n</div>\n\\`\\`\\`\n\nFor full-page dashboards:\n\n\\`\\`\\`html\n<div style=\"width: 100vw; height: 100vh;\">\n <dbn-dashboard token=\"...\" dashboard-id=\"...\"></dbn-dashboard>\n</div>\n\\`\\`\\`\n\n---\n\n## Events\n\nThe web components emit custom events that you can listen to:\n\n\\`\\`\\`javascript\nconst dashboard = document.querySelector('dbn-dashboard');\n\ndashboard.addEventListener('dbn-token-expired', (event) => {\n // Refresh the guest token and set the new one\n fetchNewGuestToken().then(newToken => {\n dashboard.setAttribute('token', newToken);\n });\n});\n\ndashboard.addEventListener('dbn-error', (event) => {\n console.error('Dashboard error:', event.detail);\n});\n\ndashboard.addEventListener('dbn-loaded', (event) => {\n console.log('Dashboard loaded successfully');\n});\n\\`\\`\\`\n\n---\n\n## Complete Example\n\n\\`\\`\\`html\n<!DOCTYPE html>\n<html>\n<head>\n <script type=\"module\">\n import '@databrainhq/plugin';\n </script>\n <style>\n #dashboard-container {\n width: 100%;\n max-width: 1200px;\n height: 800px;\n margin: 0 auto;\n }\n </style>\n</head>\n<body>\n <div id=\"dashboard-container\">\n <dbn-dashboard\n token=\"eyJhbGciOi...\"\n dashboard-id=\"dash-abc-123\"\n enable-download-csv\n enable-download-all-pdf\n enable-multi-metric-filters\n is-sticky-dashboard-filters\n is-hide-chart-settings\n options='{\n \"theme\": {\n \"general\": { \"primaryColor\": \"#4F46E5\" }\n }\n }'\n ></dbn-dashboard>\n </div>\n</body>\n</html>\n\\`\\`\\`\n`;\n","export const selfServeReferenceContent = `\n# Databrain Self-Serve Access Settings Reference\n\n## Overview\n\nAccess settings control what end users can do within an embedded dashboard or metric.\nThese settings determine whether users can create, edit, or delete metrics, change\nlayouts, use AI features, drill down into data, and more.\n\nAccess settings can be configured at three levels (from lowest to highest precedence):\n1. **Embed configuration** - Default settings for the embed\n2. **Guest token** - Runtime overrides when generating the token\n3. **Web component** - Client-side overrides via the \\`options\\` attribute\n\n---\n\n## Access Setting Flags\n\nAll access settings are boolean flags prefixed with \\`isAllow\\`. By default, most\nsettings are \\`false\\` (disabled) unless explicitly enabled.\n\n### Metric Operations\n\n| Flag | Default | Description |\n|-----------------------------|---------|----------------------------------------------------------|\n| \\`isAllowMetricCreation\\` | false | Allow users to create new metrics in the dashboard |\n| \\`isAllowMetricDeletion\\` | false | Allow users to delete existing metrics |\n| \\`isAllowMetricEditing\\` | false | Allow users to edit/modify metric configurations |\n| \\`isAllowMetricDrag\\` | false | Allow users to drag and reposition metrics |\n| \\`isAllowMetricResize\\` | false | Allow users to resize metric cards |\n\n### Layout and Display\n\n| Flag | Default | Description |\n|-----------------------------|---------|----------------------------------------------------------|\n| \\`isAllowChangeLayout\\` | false | Allow users to modify the dashboard grid layout |\n| \\`isAllowFullscreen\\` | true | Allow users to view metrics in fullscreen mode |\n| \\`isAllowTablePreview\\` | true | Allow users to toggle the data table preview |\n| \\`isAllowChartSettings\\` | true | Allow users to access chart configuration panel |\n\n### Data Interaction\n\n| Flag | Default | Description |\n|-----------------------------|---------|----------------------------------------------------------|\n| \\`isAllowDrillDown\\` | false | Allow users to drill down into data points |\n| \\`isAllowCrossFilter\\` | false | Allow clicking a chart element to filter other metrics |\n| \\`isAllowSorting\\` | true | Allow users to sort data in table views |\n\n### AI Features\n\n| Flag | Default | Description |\n|-----------------------------|---------|----------------------------------------------------------|\n| \\`isAllowAiPilot\\` | false | Enable the AI Pilot for natural language data queries |\n| \\`isAllowAiSummary\\` | false | Enable AI-generated summaries of metric data |\n| \\`isAllowAiRecommendation\\` | false | Enable AI-recommended metrics and insights |\n\n### Export and Sharing\n\n| Flag | Default | Description |\n|-----------------------------|---------|----------------------------------------------------------|\n| \\`isAllowDownloadCsv\\` | false | Allow downloading individual metric data as CSV |\n| \\`isAllowEmailCsv\\` | false | Allow emailing metric data as CSV |\n| \\`isAllowDownloadAllMetrics\\` | false | Allow bulk CSV download of all dashboard metrics |\n| \\`isAllowDownloadPdf\\` | false | Allow downloading the dashboard as PDF |\n| \\`isAllowShareUrl\\` | false | Allow generating shareable URLs |\n\n### Filter Controls\n\n| Flag | Default | Description |\n|-----------------------------|---------|----------------------------------------------------------|\n| \\`isAllowDashboardFilters\\` | true | Show the dashboard filter bar |\n| \\`isAllowDateRangeFilter\\` | true | Allow date range filter selection |\n| \\`isAllowCustomDateRange\\` | false | Allow custom date range input (vs predefined ranges) |\n\n---\n\n## Metric Creation Modes\n\nWhen \\`isAllowMetricCreation\\` is enabled, you can control how users create metrics\nusing the \\`metricCreationMode\\` setting:\n\n### DRAG_DROP\nThe traditional visual metric builder. Users select dimensions, measures, and chart\ntypes through a drag-and-drop interface.\n\n\\`\\`\\`json\n{\n \"isAllowMetricCreation\": true,\n \"metricCreationMode\": \"DRAG_DROP\"\n}\n\\`\\`\\`\n\n### CHAT\nAI-powered metric creation. Users describe what they want in natural language and\nthe AI generates the metric. Requires a semantic layer on the underlying datamarts.\n\n\\`\\`\\`json\n{\n \"isAllowMetricCreation\": true,\n \"metricCreationMode\": \"CHAT\"\n}\n\\`\\`\\`\n\n> **Note**: CHAT mode requires:\n> - Semantic layer generated for the datamarts\n> - \\`isAllowAiPilot\\` should also be enabled for the best experience\n\n---\n\n## Applying Access Settings\n\n### At Embed Configuration Level\n\nSet default access settings when creating or updating an embed:\n\n\\`\\`\\`json\n{\n \"dataAppId\": \"app-123\",\n \"dashboardId\": \"dash-456\",\n \"name\": \"Customer Embed\",\n \"accessSettings\": {\n \"isAllowMetricCreation\": false,\n \"isAllowMetricEditing\": false,\n \"isAllowDrillDown\": true,\n \"isAllowDownloadCsv\": true,\n \"isAllowAiPilot\": false,\n \"isAllowDashboardFilters\": true\n }\n}\n\\`\\`\\`\n\n### Runtime Overrides via Guest Token\n\nOverride access settings at guest token generation time. This is useful for role-based\naccess where different users get different permissions:\n\n\\`\\`\\`json\n{\n \"embedId\": \"embed-789\",\n \"clientId\": \"tenant-abc\",\n \"accessSettings\": {\n \"isAllowMetricCreation\": true,\n \"isAllowMetricEditing\": true,\n \"isAllowAiPilot\": true,\n \"metricCreationMode\": \"CHAT\"\n }\n}\n\\`\\`\\`\n\nGuest token access settings **merge with and override** embed-level settings. Only the\nflags you specify are overridden; unspecified flags keep their embed-level values.\n\n### Component-Level Overrides\n\nOverride access settings via the web component \\`options\\` attribute:\n\n\\`\\`\\`html\n<dbn-dashboard\n token=\"...\"\n dashboard-id=\"...\"\n options='{\n \"accessSettings\": {\n \"isAllowDrillDown\": true,\n \"isAllowDownloadCsv\": true\n }\n }'\n></dbn-dashboard>\n\\`\\`\\`\n\n> **Security Note**: Component-level overrides are client-side and can be modified by\n> end users with browser developer tools. For security-sensitive settings, always\n> enforce them via guest token or embed configuration (server-side).\n\n---\n\n## Precedence Order\n\nWhen the same flag is set at multiple levels, the highest precedence wins:\n\n1. **Web component \\`options\\`** (highest - client-side)\n2. **Guest token \\`accessSettings\\`** (server-side, per session)\n3. **Embed configuration \\`accessSettings\\`** (server-side, default)\n\n> **Best Practice**: Set restrictive defaults at the embed level. Use guest token\n> overrides to grant additional permissions to specific users or roles. Avoid relying\n> on component-level overrides for security.\n\n---\n\n## Common Configurations\n\n### View-Only Dashboard\n\\`\\`\\`json\n{\n \"isAllowMetricCreation\": false,\n \"isAllowMetricDeletion\": false,\n \"isAllowMetricEditing\": false,\n \"isAllowChangeLayout\": false,\n \"isAllowDrillDown\": false,\n \"isAllowDashboardFilters\": true,\n \"isAllowDownloadCsv\": false\n}\n\\`\\`\\`\n\n### Power User Dashboard\n\\`\\`\\`json\n{\n \"isAllowMetricCreation\": true,\n \"isAllowMetricEditing\": true,\n \"isAllowDrillDown\": true,\n \"isAllowAiPilot\": true,\n \"isAllowDownloadCsv\": true,\n \"isAllowDownloadPdf\": true,\n \"metricCreationMode\": \"CHAT\"\n}\n\\`\\`\\`\n\n### Export-Enabled Dashboard\n\\`\\`\\`json\n{\n \"isAllowMetricCreation\": false,\n \"isAllowMetricEditing\": false,\n \"isAllowDrillDown\": true,\n \"isAllowDownloadCsv\": true,\n \"isAllowEmailCsv\": true,\n \"isAllowDownloadAllMetrics\": true,\n \"isAllowDownloadPdf\": true\n}\n\\`\\`\\`\n`;\n","export const semanticLayerGuideContent = `\n# Databrain Semantic Layer Guide\n\n## What Is the Semantic Layer?\n\nThe semantic layer is a metadata layer that sits on top of your datamarts (database tables\nand views). It provides **business context** that helps both humans and AI understand the\nmeaning and relationships in your data.\n\nWithout a semantic layer, column names like \\`cust_id\\`, \\`amt_usd\\`, or \\`cat_cd\\` are\nopaque. The semantic layer translates these into business-friendly descriptions, making\nyour data accessible to non-technical users and enabling AI-powered features.\n\n---\n\n## Components of a Semantic Layer\n\n### Table Descriptions\nA natural language description of what the table represents.\n\n**Example:**\n- Table: \\`orders\\`\n- Description: \"Contains all customer orders including order date, status, total amount, and shipping details. Each row represents a single order.\"\n\n### Column Descriptions\nA natural language description for each column explaining its meaning, valid values,\nand business context.\n\n**Example:**\n| Column | Description |\n|----------------|----------------------------------------------------------|\n| \\`order_id\\` | Unique identifier for the order |\n| \\`customer_id\\` | Foreign key linking to the customers table |\n| \\`status\\` | Order status: pending, processing, shipped, delivered, cancelled |\n| \\`total_amount\\` | Total order value in USD, including tax and shipping |\n| \\`created_at\\` | Timestamp when the order was placed (UTC) |\n\n### Synonyms\nAlternative names or terms that users might use to refer to a table or column.\nSynonyms improve AI query understanding.\n\n**Example:**\n- Column \\`total_amount\\` synonyms: \\`[\"order total\", \"revenue\", \"sale amount\", \"order value\"]\\`\n- Column \\`created_at\\` synonyms: \\`[\"order date\", \"purchase date\", \"date placed\"]\\`\n- Table \\`orders\\` synonyms: \\`[\"purchases\", \"transactions\", \"sales\"]\\`\n\n### Example Questions\nSample natural language questions that can be answered using the data in this table.\nThese serve as few-shot examples for the AI.\n\n**Example:**\n- \"What is the total revenue by month?\"\n- \"Show me the top 10 customers by order count\"\n- \"What is the average order value for each product category?\"\n- \"How many orders were cancelled last quarter?\"\n- \"What is the trend of daily orders over the past 6 months?\"\n\n---\n\n## Auto-Generation\n\nDatabrain can automatically generate semantic layer metadata using AI. This is the\nrecommended approach for initial setup.\n\n### Step 1: Generate the Semantic Layer\n\nUse the \\`generate_semantic_layer\\` tool (or API) to trigger auto-generation:\n\n\\`\\`\\`\nTool: generate_semantic_layer\nParameters:\n - datamartId: \"datamart-abc-123\"\n\\`\\`\\`\n\nThis starts an asynchronous process where the AI analyzes your table schema, column\ntypes, sample data, and relationships to generate:\n- Table description\n- Column descriptions\n- Suggested synonyms\n- Example questions\n\n### Step 2: Poll for Completion\n\nThe generation process runs asynchronously. Poll the status until completion:\n\n\\`\\`\\`\nTool: get_semantic_layer_status\nParameters:\n - datamartId: \"datamart-abc-123\"\n\\`\\`\\`\n\nStatus values:\n- \\`PENDING\\` - Generation has been queued\n- \\`IN_PROGRESS\\` - AI is analyzing the schema and generating metadata\n- \\`COMPLETED\\` - Generation is done, semantic layer is available\n- \\`FAILED\\` - Generation failed (check error details)\n\n### Step 3: Review and Refine\n\nAfter auto-generation, review the generated metadata. While AI-generated descriptions\nare usually accurate, you may want to:\n- Correct any inaccurate descriptions\n- Add domain-specific terminology\n- Add more synonyms relevant to your organization\n- Add additional example questions that reflect common business queries\n\n---\n\n## Completion Score\n\nThe semantic layer has a **completion score** (0-100%) that measures how thoroughly\nyour datamarts are documented.\n\n### How It Is Calculated\n\nThe score considers:\n- **Table description** - Does the table have a description?\n- **Column coverage** - What percentage of columns have descriptions?\n- **Synonym coverage** - Do columns have synonyms defined?\n- **Example questions** - Are example questions provided?\n\n### Why It Matters\n\n| Score Range | Impact |\n|-------------|----------------------------------------------------------------|\n| 0-25% | AI Pilot will produce poor results; basic features only |\n| 25-50% | AI can answer simple questions but struggles with ambiguity |\n| 50-75% | Good coverage; AI handles most queries accurately |\n| 75-100% | Excellent; AI Pilot performs at its best |\n\n**A higher completion score directly improves AI Pilot accuracy.** The semantic layer\nprovides the context the AI needs to:\n- Understand which columns to use for a given question\n- Resolve ambiguous terms (e.g., \"revenue\" could mean \\`total_amount\\` or \\`net_amount\\`)\n- Generate correct SQL joins between tables\n- Apply appropriate aggregations and filters\n\n---\n\n## When to Use the Semantic Layer\n\n### Required For:\n- **AI Pilot** (\\`isAllowAiPilot\\`) - The AI chat interface requires semantic layer\n context to generate accurate queries. Without it, the AI will not know what your\n columns mean and will produce unreliable results.\n- **CHAT metric creation mode** - When users create metrics via natural language,\n the semantic layer guides the AI in interpreting their requests.\n- **AI Summary** (\\`isAllowAiSummary\\`) - AI-generated data summaries use semantic\n context for more meaningful insights.\n- **AI Recommendations** (\\`isAllowAiRecommendation\\`) - Suggested metrics and insights\n rely on understanding the data model.\n\n### Recommended For:\n- **All production embeds** - Even without AI features, the semantic layer improves\n the user experience by providing descriptive column names and context in the UI.\n- **Onboarding new team members** - The semantic layer serves as living documentation\n for your data model.\n\n### Not Required For:\n- **Basic embedding without AI features** - If you only need to display pre-built\n dashboards and metrics without AI capabilities, the semantic layer is optional\n (but still recommended).\n\n---\n\n## Best Practices\n\n### 1. Start with Auto-Generation\nUse the \\`generate_semantic_layer\\` tool to create an initial baseline. This saves\nsignificant manual effort.\n\n### 2. Prioritize High-Traffic Tables\nFocus on the tables that are most frequently queried or that appear in the most\nmetrics. These benefit most from accurate semantic metadata.\n\n### 3. Use Domain-Specific Language\nWrite descriptions and synonyms in the language your business users actually use,\nnot technical database terminology.\n\n### 4. Include Edge Cases in Examples\nAdd example questions that cover edge cases, date ranges, comparisons, and\naggregations your users commonly need.\n\n### 5. Keep It Updated\nWhen your schema changes (new columns, renamed tables), regenerate or update the\nsemantic layer to stay current.\n\n### 6. Aim for 75%+ Completion\nA completion score of 75% or higher ensures reliable AI Pilot performance. Below\nthis threshold, expect decreased accuracy in AI-generated queries.\n\n---\n\n## Semantic Layer vs Raw Schema\n\n| Aspect | Raw Schema | With Semantic Layer |\n|---------------------|-----------------------------|--------------------------------------|\n| Column reference | \\`cust_id\\` | \"Customer ID - unique identifier\" |\n| AI understanding | Guesses from name | Knows exact meaning and context |\n| User experience | Technical column names | Business-friendly labels |\n| Query accuracy | Hit or miss | Consistently high |\n| Ambiguity handling | Cannot resolve | Uses synonyms and descriptions |\n`;\n","export const multiTenancyGuideContent = `\n# Databrain Multi-Tenancy Guide\n\n## Overview\n\nMulti-tenancy allows you to use a single Databrain setup to serve multiple customers\n(tenants), each seeing only their own data. This is essential for SaaS applications\nwhere a shared database contains data for many organizations, but each customer\nshould only access their own records.\n\nDatabrain enforces multi-tenancy through a combination of:\n- **clientId** in guest tokens for tenant identification\n- **clientColumn** mapping in datamarts for row-level filtering\n- **Tenancy level** configuration for table or database isolation\n\n---\n\n## Tenancy Levels\n\n### TABLE Level Tenancy\n\nThe most common approach. All tenants share the same database and tables, but each\nrow belongs to a specific tenant identified by a tenant column.\n\n**How it works:**\n- Each table has a column that identifies the tenant (e.g., \\`organization_id\\`, \\`company_id\\`, \\`tenant_id\\`)\n- When a guest token is generated with a \\`clientId\\`, Databrain automatically adds\n a \\`WHERE\\` clause filtering on the tenant column\n- End users only see rows where the tenant column matches their \\`clientId\\`\n\n**Example schema:**\n\\`\\`\\`sql\nCREATE TABLE orders (\n id SERIAL PRIMARY KEY,\n org_id VARCHAR(50), -- tenant column\n customer VARCHAR(100),\n amount DECIMAL(10,2),\n created_at TIMESTAMP\n);\n\\`\\`\\`\n\n**Configuration:**\n\\`\\`\\`json\n{\n \"tenancyLevel\": \"TABLE\",\n \"clientColumn\": {\n \"orders\": \"org_id\",\n \"customers\": \"org_id\",\n \"invoices\": \"organization_id\"\n }\n}\n\\`\\`\\`\n\n### DATABASE Level Tenancy\n\nEach tenant has their own database (or schema). Databrain routes queries to the\nappropriate database based on the \\`clientId\\`.\n\n**How it works:**\n- Each tenant's data lives in a separate database or schema\n- The \\`clientId\\` maps to a specific database connection\n- Queries are executed against the tenant-specific database\n\n**When to use:**\n- Strict data isolation requirements (compliance, regulatory)\n- Tenants with very different data volumes\n- Legacy systems where each customer already has a separate database\n\n---\n\n## clientId in Guest Tokens\n\nThe \\`clientId\\` is the primary mechanism for identifying which tenant is accessing\nthe embedded dashboard.\n\n### Setting clientId\n\nWhen generating a guest token on your backend, include the \\`clientId\\` parameter:\n\n\\`\\`\\`json\n{\n \"embedId\": \"embed-789\",\n \"clientId\": \"acme-corp\",\n \"appFilters\": [],\n \"dashboardAppFilters\": []\n}\n\\`\\`\\`\n\n### How clientId Works\n\n1. Your backend authenticates the user and determines their tenant/organization\n2. The backend generates a guest token with the appropriate \\`clientId\\`\n3. Databrain uses the \\`clientId\\` to apply row-level security:\n - For TABLE tenancy: adds \\`WHERE tenant_column = 'clientId'\\` to all queries\n - For DATABASE tenancy: routes the query to the tenant's database\n4. The end user sees only their tenant's data\n\n### Security\n\n- The \\`clientId\\` is embedded in the guest token and **cannot be modified client-side**\n- Guest tokens are short-lived and signed, preventing tampering\n- Always set \\`clientId\\` on your server, never accept it from the client\n\n---\n\n## clientColumn Mapping in Datamarts\n\nFor TABLE-level tenancy, each datamart (table) needs a **clientColumn** mapping that\ntells Databrain which column contains the tenant identifier.\n\n### Configuration\n\nThe client column mapping is set per table in the datamart configuration:\n\n\\`\\`\\`json\n{\n \"datamartId\": \"datamart-orders\",\n \"clientColumn\": \"org_id\"\n}\n\\`\\`\\`\n\n### Different Column Names Per Table\n\nDifferent tables may use different column names for the tenant identifier. The\nmapping supports per-table configuration:\n\n\\`\\`\\`json\n{\n \"clientColumnMapping\": {\n \"orders\": \"org_id\",\n \"customers\": \"organization_id\",\n \"products\": \"company_id\",\n \"events\": \"tenant_id\"\n }\n}\n\\`\\`\\`\n\n### Important Notes\n\n- Every table that should be tenant-filtered **must** have a client column mapping\n- If a table does not have a client column mapping, queries against it will return\n **all rows** regardless of tenant (this may be intentional for shared reference\n tables like countries, currencies, etc.)\n- The client column must contain values that match the \\`clientId\\` passed in the\n guest token\n\n---\n\n## tableTenancySettings in Embeds\n\nEmbed configurations can include \\`tableTenancySettings\\` to define or override\ntenancy behavior at the embed level.\n\n### Structure\n\n\\`\\`\\`json\n{\n \"dataAppId\": \"app-123\",\n \"dashboardId\": \"dash-456\",\n \"name\": \"Multi-Tenant Embed\",\n \"tableTenancySettings\": {\n \"tenancyLevel\": \"TABLE\",\n \"clientColumnMapping\": {\n \"orders\": \"org_id\",\n \"customers\": \"organization_id\",\n \"invoices\": \"company_id\"\n },\n \"sharedTables\": [\"countries\", \"currencies\", \"product_categories\"]\n }\n}\n\\`\\`\\`\n\n### sharedTables\n\nTables listed in \\`sharedTables\\` are exempt from tenant filtering. Use this for\nreference/lookup tables that contain data common to all tenants:\n\n- Country codes\n- Currency lists\n- Product category hierarchies\n- Shared configuration tables\n\n---\n\n## Complete Example: SaaS Application\n\n### Scenario\n\nYou run a SaaS project management tool. Multiple companies use your platform, and\neach company should only see their own projects, tasks, and team members.\n\n### Database Schema\n\n\\`\\`\\`sql\n-- All tables have an org_id column for tenant isolation\nCREATE TABLE projects (\n id SERIAL PRIMARY KEY,\n org_id VARCHAR(50) NOT NULL,\n name VARCHAR(200),\n status VARCHAR(20),\n budget DECIMAL(12,2)\n);\n\nCREATE TABLE tasks (\n id SERIAL PRIMARY KEY,\n org_id VARCHAR(50) NOT NULL,\n project_id INTEGER REFERENCES projects(id),\n title VARCHAR(200),\n assignee VARCHAR(100),\n status VARCHAR(20),\n due_date DATE\n);\n\nCREATE TABLE team_members (\n id SERIAL PRIMARY KEY,\n org_id VARCHAR(50) NOT NULL,\n name VARCHAR(100),\n role VARCHAR(50),\n email VARCHAR(200)\n);\n\n-- Shared reference table (no org_id)\nCREATE TABLE task_statuses (\n code VARCHAR(20) PRIMARY KEY,\n label VARCHAR(50),\n sort_order INTEGER\n);\n\\`\\`\\`\n\n### Step 1: Create Datasource and Sync\n\nConnect your database and sync to import all tables as datamarts.\n\n### Step 2: Create Data App and Assign Datamarts\n\nCreate a data app and assign the \\`projects\\`, \\`tasks\\`, \\`team_members\\`, and\n\\`task_statuses\\` datamarts.\n\n### Step 3: Configure Client Column Mapping\n\nSet the client column for each tenant-scoped table:\n\n\\`\\`\\`json\n{\n \"clientColumnMapping\": {\n \"projects\": \"org_id\",\n \"tasks\": \"org_id\",\n \"team_members\": \"org_id\"\n }\n}\n\\`\\`\\`\n\nNote: \\`task_statuses\\` has no mapping because it is a shared reference table.\n\n### Step 4: Create Dashboard and Embed\n\nCreate a dashboard in the UI with metrics like:\n- Project count by status\n- Tasks completed this month\n- Team member workload\n- Budget utilization\n\nThen create an embed configuration with tenancy settings:\n\n\\`\\`\\`json\n{\n \"dataAppId\": \"app-123\",\n \"dashboardId\": \"dash-456\",\n \"name\": \"Customer Dashboard\",\n \"tableTenancySettings\": {\n \"tenancyLevel\": \"TABLE\",\n \"clientColumnMapping\": {\n \"projects\": \"org_id\",\n \"tasks\": \"org_id\",\n \"team_members\": \"org_id\"\n },\n \"sharedTables\": [\"task_statuses\"]\n }\n}\n\\`\\`\\`\n\n### Step 5: Generate Guest Tokens Per Tenant\n\nOn your backend, when a user from \"Acme Corp\" (org_id = \"acme\") logs in:\n\n\\`\\`\\`typescript\n// Server-side\nconst guestToken = await fetch('https://api.usedatabrain.com/api/v2/guest-token/create', {\n method: 'POST',\n headers: {\n 'Authorization': \\`Bearer \\${apiToken}\\`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n embedId: 'embed-789',\n clientId: 'acme', // Maps to org_id values in the database\n }),\n});\n\\`\\`\\`\n\nWhen a user from \"Globex\" (org_id = \"globex\") logs in:\n\n\\`\\`\\`typescript\nconst guestToken = await fetch('https://api.usedatabrain.com/api/v2/guest-token/create', {\n method: 'POST',\n headers: {\n 'Authorization': \\`Bearer \\${apiToken}\\`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n embedId: 'embed-789',\n clientId: 'globex',\n }),\n});\n\\`\\`\\`\n\n### Step 6: Render\n\nBoth users see the same dashboard layout and metrics, but:\n- Acme sees only their projects, tasks, and team members\n- Globex sees only their projects, tasks, and team members\n- Both see all task statuses (shared reference table)\n\n### Result\n\n\\`\\`\\`\nAcme User sees:\n - 12 projects (all with org_id = 'acme')\n - 87 tasks\n - 15 team members\n\nGlobex User sees:\n - 8 projects (all with org_id = 'globex')\n - 45 tasks\n - 9 team members\n\\`\\`\\`\n\n---\n\n## Best Practices\n\n### 1. Always Set clientId Server-Side\nNever accept the \\`clientId\\` from the client. Determine the tenant from your\napplication's authentication/session layer.\n\n### 2. Map All Tenant-Scoped Tables\nEnsure every table that contains tenant-specific data has a client column mapping.\nMissing mappings will leak data across tenants.\n\n### 3. Explicitly Mark Shared Tables\nUse \\`sharedTables\\` to document which tables are intentionally unfiltered. This\nmakes the configuration self-documenting and prevents accidental data exposure.\n\n### 4. Use Consistent Tenant Column Values\nEnsure the \\`clientId\\` values you pass in guest tokens exactly match the values\nin your database tenant columns. Mismatches (case sensitivity, leading/trailing\nspaces) will result in empty dashboards.\n\n### 5. Test with Multiple Tenants\nAlways test your embedding with at least two different \\`clientId\\` values to verify\nthat data isolation is working correctly.\n\n### 6. Combine with appFilters for Fine-Grained Control\nYou can use \\`appFilters\\` alongside \\`clientId\\` for additional filtering within a\ntenant. For example, filter by department or user role within an organization.\n`;\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { gettingStartedContent } from './content/getting-started.js';\nimport { apiReferenceContent } from './content/api-reference.js';\nimport { embeddingGuideContent } from './content/embedding-guide.js';\nimport { filterReferenceContent } from './content/filter-reference.js';\nimport { themeReferenceContent } from './content/theme-reference.js';\nimport { webComponentReferenceContent } from './content/web-component-reference.js';\nimport { selfServeReferenceContent } from './content/self-serve-reference.js';\nimport { semanticLayerGuideContent } from './content/semantic-layer-guide.js';\nimport { multiTenancyGuideContent } from './content/multi-tenancy-guide.js';\n\ninterface ResourceDef {\n uri: string;\n name: string;\n description: string;\n content: string;\n}\n\nconst resources: ResourceDef[] = [\n {\n uri: 'databrain://getting-started',\n name: 'Getting Started',\n description: 'Entity model, onboarding funnel, quick-start checklist, and common pitfalls',\n content: gettingStartedContent,\n },\n {\n uri: 'databrain://api-reference',\n name: 'API Reference',\n description: 'Summarized API reference covering key endpoints, parameters, and examples',\n content: apiReferenceContent,\n },\n {\n uri: 'databrain://embedding-guide',\n name: 'Embedding Guide',\n description: 'Framework-specific embedding instructions for React, Next.js, Vue, Angular, Svelte, SolidJS, and vanilla JS',\n content: embeddingGuideContent,\n },\n {\n uri: 'databrain://filter-reference',\n name: 'Filter Reference',\n description: 'Filter types, operators, and usage patterns for guest tokens, runtime, and dashboard-level filters',\n content: filterReferenceContent,\n },\n {\n uri: 'databrain://theme-reference',\n name: 'Theme Reference',\n description: 'Theme properties, predefined vs custom themes, color and branding customization',\n content: themeReferenceContent,\n },\n {\n uri: 'databrain://web-component-reference',\n name: 'Web Component Reference',\n description: 'Complete property reference for dbn-dashboard and dbn-metric web components',\n content: webComponentReferenceContent,\n },\n {\n uri: 'databrain://self-serve-reference',\n name: 'Self-Serve Reference',\n description: 'Access settings, metric creation modes, runtime permission overrides',\n content: selfServeReferenceContent,\n },\n {\n uri: 'databrain://semantic-layer-guide',\n name: 'Semantic Layer Guide',\n description: 'Semantic layer configuration for AI chat mode, auto-generation workflow',\n content: semanticLayerGuideContent,\n },\n {\n uri: 'databrain://multi-tenancy-guide',\n name: 'Multi-Tenancy Guide',\n description: 'Multi-tenant embedding with row-level security using clientId and clientColumn',\n content: multiTenancyGuideContent,\n },\n];\n\nexport function registerAllResources(server: McpServer): void {\n for (const res of resources) {\n server.resource(res.name, res.uri, { description: res.description }, async () => ({\n contents: [\n {\n uri: res.uri,\n mimeType: 'text/markdown',\n text: res.content,\n },\n ],\n }));\n }\n}\n","export const exploreDataPrompt = `You are helping the user explore what data and resources are available in their Databrain workspace. Gather a complete picture and provide actionable recommendations.\n\n**Step 1 — Inventory All Resources**\nIf the user has an API token configured, call all of these to build a full picture:\n- \\`list_datasources\\` — connected databases\n- \\`list_data_apps\\` — workspace containers\n- \\`list_datamarts\\` — configured data models and table selections\n- \\`list_dashboards\\` — created dashboards\n\nIf any call fails due to missing authentication, note which resources could not be retrieved and advise the user to set up an API token first.\n\n**Step 2 — Summarize the Data Landscape**\nPresent a clear summary organized by data app:\n- For each data app, list its datasources, datamarts, dashboards, and embeds.\n- Highlight key details: number of tables in each datamart, whether semantic layers are configured, whether embeds exist, and any multi-tenant settings.\n- Call out anything that looks incomplete (e.g. a datamart with no dashboard, a dashboard with no embed).\n\n**Step 3 — Suggest Next Steps**\nBased on what you find, recommend the most relevant next actions:\n\nIf **no resources exist at all**:\n- Suggest running the \\`setup-from-scratch\\` prompt to get started with the full onboarding funnel.\n\nIf **datasources exist but no datamarts**:\n- Suggest creating datamarts to model the data for dashboarding.\n\nIf **datamarts exist but no dashboards**:\n- Suggest the user create dashboards in the Databrain UI.\n\nIf **dashboards exist but no embeds**:\n- Suggest running the \\`embed-dashboard\\` prompt to embed a dashboard.\n\nIf **embeds exist but AI chat is not enabled**:\n- Suggest running the \\`setup-ai-chat\\` prompt to enable AI-powered data exploration.\n\nIf **everything is set up**:\n- Confirm the workspace looks complete.\n- Suggest enabling multi-tenancy if not configured (reference the \\`setup-multi-tenant\\` prompt).\n- Suggest regenerating the semantic layer if the schema has changed recently.\n\nBe concise but thorough. The goal is to give the user a clear understanding of their current state and a clear path forward.`;\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { exploreDataPrompt } from './explore-data.js';\n\ninterface PromptDef {\n name: string;\n description: string;\n content: string;\n}\n\nconst prompts: PromptDef[] = [\n {\n name: 'explore-data',\n description: 'Explore what data and dashboards are available in your Databrain workspace',\n content: exploreDataPrompt,\n },\n];\n\nexport function registerAllPrompts(server: McpServer): void {\n for (const prompt of prompts) {\n server.prompt(prompt.name, prompt.description, async () => ({\n messages: [\n {\n role: 'user' as const,\n content: {\n type: 'text' as const,\n text: prompt.content,\n },\n },\n ],\n }));\n }\n}\n"],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACA9B,IAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACA5B,IAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACA9B,IAAM,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACA/B,IAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACA9B,IAAM,+BAA+B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACArC,IAAM,4BAA4B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAlC,IAAM,4BAA4B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAlC,IAAM,2BAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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","names":["z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","kebabCase","buildAttributes","kebabCase","buildAttributes","kebabCase","buildAttributes","kebabCase","buildAttributes","kebabCase","buildAttributes","kebabCase","buildAttributes","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","name","id","embedId"]}
|