Skip to main content
Glama

Bella — an enterprise MCP server for Claude

tests

Course repo for "Build an Enterprise MCP Server: Connect Claude to Your Company's Data" by Victor Velázquez.

Bella is the AI data analyst of Brightline Outdoor (a fictional outdoor-gear retailer). She lives behind an MCP server, so you can ask Claude — Desktop, Code or claude.ai — "who were our top Enterprise customers this year?" and get an answer from the company database, safely.

You ─▶ Claude ─▶ MCP ─▶ Bella ─▶ guard ─▶ SQLite (read-only)
                        │  5 tools · 1 resource · 1 prompt
                        └─ auth (none / JWT / GitHub OAuth) · scopes · PII masking · audit · rate limits
  • ✅ Runs with zero API keys: Bella's brain uses your Claude subscription through Claude Code (or an API key, or a free demo mode)

  • ✅ stdio and Streamable HTTP · MCP spec 2026-07-28 via FastMCP 4

  • ✅ OAuth 2.1 resource server · roles → scopes → tools · column-level PII masking

  • ✅ 59 tests, including auth over real HTTP and the stdio transport — CI on every push


Run it in 3 minutes

git clone https://github.com/victor-velazquez-ai/bella-mcp-course.git
cd bella-mcp-course
python -m venv .venv
.venv\Scripts\activate            # macOS/Linux: source .venv/bin/activate
pip install -e ".[dev]"
python data/seed.py               # builds data/bella.db (also auto-built on first start)
python verify.py                  # everything green? you're ready

Then connect it to Claude (details and 4 options in docs/connect-to-claude.md):

claude mcp add bella -- python -m bella_mcp        # Claude Code, from the activated venv

Ask: "Using Bella, how did revenue evolve by month this year, and which products are about to run out?"

Related MCP server: SafeSQL

Bella's surface

#

Tool

What

Scope

1

sales_summary

revenue, orders, units, AOV, margin % by month / category / region / channel

bella:read

2

top_customers

top customers by revenue for a period, optional segment

bella:read

3

inventory_alerts

products at/below reorder level, days of cover, suggested reorder

bella:read

4

customer_profile

360° view of one customer (by id, name or email)

bella:read

5

ask_bella

general query: plain English (Bella writes the SQL) or a read-only SELECT

bella:query

Plus the resource bella://schema (schema + business glossary) and the prompt monthly_business_review(month). All tools are annotated readOnlyHint: true and return structured output.

Security: six layers between a prompt and your data

1 scopes      ask_bella needs bella:query — without it the tool is invisible        auth.py
2 shape       exactly one SELECT / WITH statement                                    db.py
3 read-only   SQLite opened with mode=ro                                             db.py
4 authorizer  reads only; emails read as NULL without bella:pii (aliases can't help) db.py
5 limits      200 rows · 2 s timeout · 1 MB values                                   db.py
6 audit       every call → logs/audit.jsonl (who, tool, args, ms, outcome) + rate limit  audit.py

The SQL Bella's own brain writes is treated as untrusted input and goes through the same guard. Try to break it: python lessons/03_attack_the_guard.py.

Auth modes

BELLA_AUTH_MODE

For

How

none (default)

stdio, local dev

local user gets BELLA_LOCAL_ROLE (default analyst)

jwt

tokens from any IdP

signature + issuer + audience + expiry + scopes. Local IdP: python scripts/mint_token.py analyst

github

claude.ai custom connector

full OAuth 2.1 login via GitHub (OAuth proxy, PKCE, discovery metadata)

Roles: viewer (bella:read) · analyst (+ bella:query) · admin (+ bella:pii). Details and Entra ID / Okta / Auth0 / Keycloak setup: docs/auth.md.

Repo map (course Part 2 → files)

Step

Files

P1 setup

pyproject.toml, data/seed.py, verify.py

P2 MCP in 10 lines · what Claude sees

lessons/01_hello_mcp.py, lessons/02_what_claude_sees.py

P3 data layer & SQL guard

src/bella_mcp/db.py, lessons/03_attack_the_guard.py

P4 the 4 presets

src/bella_mcp/server.py

P5 ask_bella + Bella's brain

src/bella_mcp/server.py, src/bella_mcp/brain.py

P6 enterprise layer

src/bella_mcp/auth.py, src/bella_mcp/audit.py, scripts/mint_token.py

P7 connect to Claude

src/bella_mcp/__main__.py, .mcp.json, docs/connect-to-claude.md, Dockerfile

Plan-B demo

lessons/04_bella_tour.py

src/bella_mcp/
  config.py   settings from env (.env)          db.py      the guard (layers 2-5) + schema
  seed.py     builds the demo database          brain.py   English → SQL (Claude API / subscription / OpenAI / demo)
  auth.py     auth modes, roles, scopes         audit.py   audit middleware (layer 6)
  server.py   build_server(): tools, resource, prompt, /health
  __main__.py python -m bella_mcp [stdio|http]

Commands

python -m bella_mcp                        # stdio (Claude Desktop / Code launch this)
python -m bella_mcp http                   # http://localhost:8000/mcp  · health: /health
BELLA_AUTH_MODE=jwt python -m bella_mcp http
python scripts/mint_token.py viewer --decode
python -m pytest -q
docker build -t bella . && docker run -p 8000:8000 bella

Make it yours

Swap the data, keep the architecture, ship it, put it in your portfolio: docs/make-it-yours.md.


Built with FastMCP 4 on the Model Context Protocol. Data is synthetic. MIT licensed. Never commit your .env.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables Claude to connect to and interact with SQLite, SQL Server, PostgreSQL, and MySQL databases through natural language. Supports executing queries, managing tables, exporting data, and storing business insights with authentication options including AWS IAM.
    400 npm
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables Claude Desktop and Claude Code to inspect a Postgres schema and run read-only SQL queries against a demo database through the tools describe_schema and query_readonly. Every proposed query passes the same deterministic guardrails — SELECT-only, allow-listed tables, enforced row limits, statement timeouts and a read-only role — before execution.
    2
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables Claude to answer questions about a small business's own data by providing predefined sales, customer, refund, and inventory tools, plus a guarded read-only SQL query tool with audit logging.
    6
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables Claude to query and safely write to a Postgres database, driven entirely by one policy file with read-only access by default, column-precise PII masking, and an append-only audit log. SQL is parsed and validated before execution, writes use parameterized queries with dry-run/confirm and transactions, and every call is rate-limited and audited so destructive or exfiltrating requests are refused.
    MIT