How to Build Customer-Facing Analytics for B2B SaaS A developer compares approaches to building customer-facing analytics for B2B SaaS, arguing that embedding BI tools like Metabase or Looker leads to multi-tenancy and branding issues, while building custom charts from scratch incurs high maintenance costs. The post introduces @bonnard/mcp-charts as a solution for AI agent surfaces where customers query data via Claude or ChatGPT. Your B2B customers want to see their data. Usage metrics, billing summaries, conversion funnels, performance dashboards. Every customer expects analytics inside your product. They shouldn't have to ask your support team for a CSV export. The question isn't whether to ship customer-facing analytics. It's how. Most teams start with one of two approaches. They embed a BI tool Metabase, Looker, Power BI and fight with multi-tenancy, iframe styling, and paid embedding licenses. Or they build custom charts from scratch and spend months maintaining SQL queries, API endpoints, and frontend components that nobody asked for. Both approaches burn engineering time on the wrong problem. You end up building analytics infrastructure instead of your product. And there's a surface most of these tools miss entirely: the AI agent. Customers increasingly want to ask questions about their data inside Claude or ChatGPT and get a chart back. That's a different problem from embedding a dashboard, and it's where @bonnard/mcp-charts fits, covered later in this post. Embedding a BI tool sounds fast. Drop in an iframe, connect to your database, ship it. In practice, the friction shows up quickly. Most BI tools were built for internal teams, not B2B products serving hundreds of tenants. Multi-tenancy is either missing, manual, or gated behind an enterprise license. Metabase https://bonnard.dev/vs-metabase requires the Enterprise license $500+/month for row-level permissions and sandboxed embedding. The open-source version has basic embedding but no tenant isolation. You end up writing middleware to filter queries by tenant, which is exactly the custom infrastructure you were trying to avoid. Looker's embedded analytics requires an enterprise contract. Power BI Embedded uses capacity-based pricing that gets expensive at scale. Tableau's embedding story is Salesforce-priced. Even when multi-tenancy is available, it's usually dashboard-level or role-based, not per-query structural enforcement. You're trusting the BI tool to filter correctly on every query. One misconfiguration and Customer A sees Customer B's data. An iframe is a foreign element in your product. It looks like a foreign element. Matching your brand's fonts, colors, spacing, and interaction patterns inside an embedded BI tool ranges from difficult to impossible. Your customers notice. White-label analytics means your customers shouldn't know they're using a third-party tool. Most embedded BI solutions make this hard. The ones that make it easy charge for it. Embedded BI gives you dashboards. That's one surface. But your customers might also want: Each of these requires a different integration, often with different tools and different metric definitions. The dashboard shows one number. The API returns a different one. The export uses yet another query. The metrics drift. The alternative: skip the BI tool and build it yourself. Custom SQL queries, custom API endpoints, custom React charts. This works for the first dashboard. Then the second. By the tenth, you're maintaining a bespoke analytics platform. Every new metric means a new SQL query, a new API endpoint, a new frontend component, and a new set of tests. Your data engineers are writing API handlers instead of defining metrics. Your frontend engineers are debugging chart edge cases instead of building product features. The real cost isn't the initial build. It's the ongoing maintenance: The teams on Reddit asking "Is embedded analytics for SaaS actually worth it vs building your own charts?" https://www.reddit.com/r/analytics/comments/1pxjm1z/ are wrestling with exactly this tradeoff. There's no single right answer. The decision depends on how many surfaces you serve and whether your customers want charts in a dashboard, an API, or an AI agent. The sections above cover the two classic customer-facing analytics options: embed a BI tool or build dashboards from scratch. There's a third surface that neither covers well: the AI agent. When your customer asks a question in Claude or ChatGPT and wants a chart back, an embedded dashboard doesn't help. @bonnard/mcp-charts is the MCP-native option for that surface. It is not an embedded BI tool, a dashboard product, or a multi-tenant analytics platform. It is a visualize tool you add to your MCP server that renders interactive charts from your query results, inside the agent. Install the package and call addCharts with your existing MCP server and a runSql function: js import { addCharts } from "@bonnard/mcp-charts"; addCharts server, { runSql: async sql = { // Run the query against your database and return typed rows. return await db.query sql ; }, } ; addCharts registers a visualize tool and a visualize read me companion on your server. The flow: visualize with a query. runSql returns rows. ui:// widget in Claude or ChatGPT.Chart types: line, bar, area, pie, scatter, funnel, waterfall, and table. Bar charts have stacked, grouped, horizontal, and 100% variants, and a donut is a pie variant. Axes, formatting, and gap-fill are determined automatically, so the same query produces the same chart. Native adapters cover Postgres, BigQuery, Snowflake, Databricks, and DuckDB. You can also pass your own runSql . Bonnard never touches your database. Your code runs the query and returns the rows. The visualize tool returns compact summaries, row caps with completeness flags, and a typed schema so the agent can reason about the result. Errors are instructive and include a next step , so when a query fails the agent knows what to try next. For how this is designed, see how Bonnard builds agent-friendly MCPs https://bonnard.dev/blog/how-bonnard-builds-agent-friendly-mcps . | Build from scratch | Embed BI tool | Charts in AI agent MCP | | |---|---|---|---| Surface | In your product UI | In your product UI | Inside Claude or ChatGPT | Time to first chart | 2-4 months | 1-2 weeks | A few lines addCharts | What renders the chart | Your frontend code | The BI tool | The agent host ui:// widget | Where the query runs | Your code | The BI tool | Your runSql , your database | Chart types | Whatever you build | Tool's library | line, bar, area, pie, scatter, funnel, waterfall, table | Maintenance burden | High you own everything | Medium tool updates, iframes | Low one tool registration | AI agent support | Build from scratch | None | Native visualize tool | These are not competing for the same slot. Embedded BI and a from-scratch build put charts in your product UI. Charts in the agent put them inside Claude or ChatGPT. Many teams will do both. Embedded analytics tools Metabase Embedded, Holistics, Explo, Luzmo, Reveal give you dashboards inside your product. That's their scope. They're good at it. None of them render a chart inside an AI agent. @bonnard/mcp-charts is the adjacent option, not a member of the embedded BI category: 1. The chart lives in the agent. When a customer asks a question in Claude or ChatGPT, the visualize tool renders an interactive ui:// widget right in the conversation. An embedded dashboard can't do that. 2. Your database stays yours. Bonnard never touches your database. Your runSql runs the query and returns the rows. Bonnard infers the chart from the typed result. 3. Designed for the agent. Compact summaries, row caps with completeness flags, typed schema, and instructive errors with a next step . The tool is built for an agent to call, not only for a human to read. The tradeoff: embedded BI tools render charts in your product UI, which is where many customers expect them. @bonnard/mcp-charts only covers the agent surface. If your customers want both a dashboard and an in-agent chart, use an embedded BI tool for the dashboard and @bonnard/mcp-charts for the agent. Install the package and register the tool on your MCP server: npm install @bonnard/mcp-charts js import { addCharts } from "@bonnard/mcp-charts"; addCharts server, { runSql: async sql = db.query sql , } ; That registers the visualize tool and visualize read me . Connect your server in Claude or ChatGPT, and the agent can render charts from your query results. Native adapters cover Postgres, BigQuery, Snowflake, Databricks, and DuckDB, or pass your own runSql . Repo: github.com/bonnard-data/mcp-charts https://github.com/bonnard-data/mcp-charts . For the full walkthrough: MCP charts https://bonnard.dev/blog/mcp-charts . For the design principles: how Bonnard builds agent-friendly MCPs https://bonnard.dev/blog/how-bonnard-builds-agent-friendly-mcps . Customer-facing analytics is analytics embedded in your product for your customers to use. Instead of internal dashboards for your team, the analytics are exposed to end users: your B2B customers, their teams, and their tools. The key challenges are multi-tenancy each customer sees only their data , performance customers expect fast load times , and consistency the numbers should match across every surface . Embedded analytics https://bonnard.dev/glossary/embedded-analytics means integrating analytics capabilities directly into another application. This can be as simple as an iframe embedding a dashboard or as sophisticated as native React components querying a governed API. The term covers a range of approaches from basic chart embedding to full white-label analytics platforms. Metabase https://bonnard.dev/vs-metabase offers embedded dashboards via iframe or full-app embedding. The open-source version has basic embedding but no tenant isolation. The Enterprise version $500+/month adds row-level permissions and sandboxed embedding. Metabase renders charts in your product UI. @bonnard/mcp-charts is a different surface entirely: it renders interactive charts inside an AI agent Claude or ChatGPT via a visualize tool on your MCP server. They are not substitutes. Use Metabase for an in-product dashboard, and @bonnard/mcp-charts for charts in the agent. White-label analytics means your customers see your brand, not a third-party tool's brand. No "Powered by Metabase" footer. No foreign-looking iframe. The analytics feel native to your product. Most embedded BI tools charge for white-labeling, and the harder it is to match your design, the more obvious the third-party tool becomes. This is a property of in-product embedding, not of charts rendered inside an AI agent. It is letting your customers ask questions about their data inside an AI agent Claude or ChatGPT and get a chart back. @bonnard/mcp-charts covers this with a visualize tool you add to your MCP server. The agent calls visualize , your runSql returns rows, and Bonnard renders an interactive chart in the conversation. This is the 2026 surface that embedded BI tools do not address. Yes, if you expose an MCP server. Add @bonnard/mcp-charts with addCharts server, { runSql } , and the agent can call visualize to render interactive charts from your query results in Claude or ChatGPT. Your runSql runs the query against your database, so Bonnard never touches your data. See MCP https://bonnard.dev/glossary/mcp for how the protocol works. Native adapters cover Postgres https://bonnard.dev/integrations/postgres , BigQuery https://bonnard.dev/integrations/bigquery , Snowflake https://bonnard.dev/integrations/snowflake , Databricks https://bonnard.dev/integrations/databricks , and DuckDB https://bonnard.dev/integrations/duckdb . You can also pass your own runSql function to query anything that returns rows. Bonnard never connects to your database directly. It is open source. Install it with npm install @bonnard/mcp-charts . Repo: github.com/bonnard-data/mcp-charts https://github.com/bonnard-data/mcp-charts .