← Projects · MCP Protocol · Open Source
Lumenore Analytics MCP Server
FastMCP · async Python 3.13 · aiohttp · Streamable HTTP · Docker
A production MCP server that makes a commercial BI/analytics platform natively accessible to any MCP-compatible AI assistant — natural-language querying, forecasting, correlations, and outlier detection over typed tools. Published open source under the Lumenore Platform organization.
Problem
AI assistants like Claude and ChatGPT had no way to query the analytics platform directly — every user copy-pasted data into the chat window, and non-technical business users couldn’t self-serve without SQL or BI training. The goal: expose the platform through the Model Context Protocol so any compatible assistant can discover and call analytics capabilities at runtime, with each request carrying its own caller credentials.
My role
I designed and implemented the server: framework selection, the typed tool surface, the asyncio/aiohttp concurrency model with connection pooling, the header-based per-request credential pass-through, streamed natural-language-query responses, and the Docker deployment.
Architecture
The tool surface. Seven analytics tools, discoverable at runtime by any host — natural-language-query-to-data, trend, prediction, correlation, outlier, change, and Pareto analysis — plus dataset-discovery and column-level-schema helpers. Each is a single-responsibility async def with typed Pydantic parameters, validated against a schema id, and returns natural-language errors an LLM can act on.
Credential pass-through, not a session store. A middleware layer lifts caller credentials off the request headers into a per-request context; the server holds no local session or database, and forwards either a bearer token or a client-credentials login to the backend on the caller’s behalf. Multi-tenant by construction — each request is scoped to whoever made it.
Tech stack
Key design decisions & trade-offs
- asyncio + aiohttp over threads. The server is pure I/O — every tool proxies to the backend — so a single event loop with a pooled async HTTP client fits far better than a thread-per-request model. Trade-off: the process must stay strictly non-blocking (a sync auth path is a known wart I’d move to aiohttp).
- Connection pooling. A reused
aiohttp.TCPConnectorwith explicit total/per-host limits and DNS caching avoids a fresh TCP + TLS handshake on every backend call. - Header-based credential pass-through over a session store. Credentials ride each request and are dropped after it; nothing is persisted server-side, so instances stay stateless and horizontally scalable, and a caller can only reach what its own credentials allow.
- FastMCP over the raw MCP SDK. Decorator-based tools with schemas auto-generated from type hints — dramatically less boilerplate across the tool surface, and Streamable HTTP transport out of the box.
- Thin server, heavy backend. All analytics computation stays in the Lumenore engine; the MCP server only translates, authenticates, and streams — keeping it small and easy to reason about.
Results
7 typed analytics tools (+ dataset/metadata helpers) · connection-pooled async client · streamed NLQ responses · MIT-licensed, published open source
Shipped as the AI-assistant integration layer for a commercial BI platform: any MCP-compatible assistant can discover the tool surface and query enterprise analytics in natural language, with per-request credential isolation and no server-side state.