
Vibe analytics for the data engineer: From request backlog to rapid prototyping
TL;DR: We built a production MCP server to expose Fabi's AI analyst agent to other LLM-powered apps and workflows, expecting a smooth implementation. Instead, we encountered OAuth quirks across different clients, inconsistent streaming support, and discovered why most MCP servers are just disquised API wrappers. From handling long-running agent calls to navigating evolving specs and authentication headaches, here's what we learned about building MCP servers that actually work in production.
Fabi.ai is an AI-powered data analyst that connects directly to your databases and helps you generate insights, build dashboards, and automate reporting—all through natural language conversations. As a comprehensive AI BI platform, Fabi enables self-service analytics, AI data visualization, and AI reporting without requiring SQL expertise.
With Fabi's Model Context Protocol (MCP) server, you can integrate these AI data analysis capabilities directly into your development tools and AI assistants. Enable ChatGPT, Claude, Cursor, or any MCP-compatible tool to chat with your data, perform ad hoc analysis, create Python dashboards, and save Smartbooks programmatically—all without leaving your data workflow. Whether you're doing Python data analysis or need a full BI platform for data collaboration, it's the fastest way to add AI-powered data analysis to any application or interface.
When we started building our Fabi MCP server, we thought it would be a smooth ride. After all, MCP has been around for about a year, with growing adoption across agentic ecosystems like ChatGPT, Claude, Cursor, and Claude Code, not to mention workflow tools such as AgentKit and n8n.
Our goal seemed simple: Expose Fabi's analyst agent as a callable tool that other LLM-powered apps or workflows could use.
This agent doesn't just spit out answers—it reasons deeply, calls RAG, performs dry-run code execution, troubleshoots intermediate steps, and returns a well-grounded, reliable conclusion. In other words, it's an agent-to-agent collaboration layer.
For security reasons, we wanted to host and deploy the server entirely within our own network. Sounds straightforward, right?
Spoiler: it wasn't.
What followed was an unexpected journey into evolving specs, mismatched OAuth flows, and client quirks. Here's what we learned and what you should watch out for if you're heading down the same path.
MCP, short for Model Context Protocol, is an open standard designed to unify how LLMs and AI apps connect to external tools, data, and workflows. Think of it as a universal adapter — a “USB-C port for AI systems.” Instead of hardcoding integrations, LLMs can auto-discover and call external resources through MCP.

Unlike traditional APIs where endpoints are rigid and schemas are tightly defined, MCP tools are meant to be semantic, flexible, and context-friendly. They’re designed for LLM reasoning, not just machine-to-machine communication.
That distinction matters. Many existing “MCP servers” are just API wrappers. They map endpoints to tools but fail to simplify or abstract their logic for LLMs. In our experience, those wrappers are of little use.
Here’s the problem: APIs are precise and parameter-heavy. LLMs prefer minimalism and intent-driven interfaces. When you try to expose raw APIs through MCP, you end up frustrating the model — and the user. For example, we once connected to a popular product analytics MCP server and asked for the number of active users. The LLM immediately asked:
At that point, if I need to supply all those details, why bother with MCP at all? I might as well call the API directly. Even worse, when multiple MCP servers are connected, LLMs start struggling to pick the right tool. Too many tools, too much context confusion and the model’s performance drops sharply.
Lesson learned: Build tools that represent intent, not implementation. MCP tools should be simple, abstracted, and aligned with natural reasoning, not replicas of REST endpoints.
Our analyst agent isn’t a one-shot call. It reasons iteratively, performing RAG, code dry-runs, and multi-step evaluations. Some analyses take one or two minutes, so we rely on streaming responses in our web app. In theory, MCP supports this. Tool calls can include a progress token, and clients can subscribe to stream updates. In practice, though:
To make it work, we had to get creative. Our MCP server responds early and provides a polling tool for long-running calls, allowing clients to fetch intermediate status or final results asynchronously.
A word of caution: MCP is phasing out SSE (Server-Sent Events) in favor of streamable HTTP. Choose your stack accordingly or risk reworking it later.
Because Fabi connects to customer data sources, our MCP server needed robust authentication and authorization. We implemented both:
OAuth is a standard, right? Sure, until every client interprets it slightly differently. Here’s what tripped us up:
/ to route paths. ChatGPT, as a client, handled it fine, but Claude stripped it during redirect — causing authentication failures. The annoying trailing slash = one lost afternoon./.well-known/oauth-protected-resource others /.well-known/oauth-protected-resource/mcp./mcp endpoint delaying it until after OAuth. This led some MCP clients to silently submit unauthenticated calls — making us think OAuth was broken when it wasn’t. Another “protocol gotchas” you only discover by faceplanting into it once. Always return 401 immediately when no valid token is present. Fail fast.We use Auth0, which creates a new app per registration. Unfortunately, Auth0 caps app counts, making it a terrible fit for MCP. You’ll either need an auth proxy or a different authorization server vendor entirely.
TL;DR: Don’t use Auth0 for MCP unless you enjoy debugging OAuth flows at 2 a.m.
Building the Fabi MCP server was a humbling experience. We expected a straightforward implementation, but ended up in a maze of spec quirks, evolving standards, and unpredictable client behaviors. That said, MCP's vision of universal, interoperable AI tool integration is absolutely the right direction, enabling seamless data collaboration and self-service analytics across any AI BI platform or data workflow.
We're early adopters on a protocol that's still maturing, and that's part of the fun. The result is a powerful integration that brings AI data analysis, AI data visualization, and AI reporting capabilities to any MCP-compatible tool, whether you're performing ad hoc analysis, building Python dashboards, or conducting Python data analysis within your existing BI platform.
If you're building your production-ready secure MCP server:
Huge thanks to Till Dohmen from MotherDuck for the valuable discussions and insights. Your shared experience helped us navigate more smoothly through this MCP labyrinth.