Faisalaffan Blog
|
🇬🇧
Faisalaffan Blog
Engineering10 min read

MCP: The Protocol That Lets AI Talk Directly to Your Database, Firebase, and Grafana

Model Context Protocol (MCP) is an open standard connecting LLMs with external data and tools — like USB-C for AI. Learn the architecture, how it works, and my real-world setup: 11 MCP servers from MySQL, Firebase, Grafana LGTM, to Lighthouse.

Faisal Affan
Faisal Affan
Published
Gallery
1 / 3

MCP: "USB-C" for AI

"The best interface is one that disappears." — Don Norman

TL;DR

Model Context Protocol (MCP) is an open protocol created by Anthropic that standardizes how AI connects to external data and tools. Think of it like USB-C for AI — one standard connection for everything.


The Problem MCP Solves

Prior to MCP, every AI integration with an external tool had to be built custom, one by one. Want to connect to MySQL? Build it yourself. Need access to Firebase? Build another. Grafana? One more.

The result? The M x N integration problem — where M is the number of AI apps and N is the number of tools.

graph LR
    A[Claude Code] -->|Custom API| D[MySQL]
    A -->|Custom API| E[Firebase]
    A -->|Custom API| F[Grafana]
    B[Gemini CLI] -->|Custom API| D
    B -->|Custom API| E
    B -->|Custom API| F
    C[Cursor] -->|Custom API| D
    C -->|Custom API| E
    C -->|Custom API| F
    style A fill:#7c3aed,color:#fff
    style B fill:#4285f4,color:#fff
    style C fill:#0ea5e9,color:#fff

With MCP, the M x N problem becomes M + N — each AI app only needs one MCP client, and each tool only needs one MCP server.

graph LR
    A[Claude Code] -->|MCP| G[MCP Protocol]
    B[Gemini CLI] -->|MCP| G
    C[Cursor] -->|MCP| G
    G -->|MCP| D[MySQL]
    G -->|MCP| E[Firebase]
    G -->|MCP| F[Grafana LGTM]
    G -->|MCP| H[Lighthouse]
    style A fill:#7c3aed,color:#fff
    style B fill:#4285f4,color:#fff
    style C fill:#0ea5e9,color:#fff
    style G fill:#f59e0b,color:#000

MCP Architecture

MCP follows a client-server architecture inspired by the Language Server Protocol (LSP). Its three main components are:

graph TB
    subgraph Host["MCP Host (Gemini CLI / Claude Code)"]
      C1[MCP Client 1]
      C2[MCP Client 2]
      C3[MCP Client 3]
      C4[MCP Client 4]
      C5[MCP Client 5]
    end
    C1 <-->|stdio| S1[Firebase MCP]
    C2 <-->|stdio| S2[MySQL dbhub]
    C3 <-->|stdio| S3[LGTM Stack]
    C4 <-->|SSE| S4[Context7]
    C5 <-->|stdio| S5[Lighthouse]
    S1 <--> FB[(Firebase)]
    S2 <--> DB[(MySQL)]
    S3 <--> GR[(Grafana/Loki/Tempo)]
    S4 <--> DOCS[(Documentation)]
    S5 <--> WEB[(Web Pages)]
    style Host fill:#1e1b4b,color:#fff
    style S1 fill:#059669,color:#fff
    style S2 fill:#059669,color:#fff
    style S3 fill:#059669,color:#fff
    style S4 fill:#d97706,color:#fff
    style S5 fill:#059669,color:#fff

Three Core Primitives

An MCP server exposes three types of capabilities:

PropertyTypeDescription
Tools Function Functions an LLM can call to perform actions. Example: querying a database, creating an issue, sending a message.
Resources Data Source Data sources an LLM can access (read-only). Similar to a GET endpoint in a REST API. Example: file content, database schema.
Prompts Template Templates optimized to use tools and resources effectively.

Simple Analogy

MCP Primitive REST API Analogy Example
Tools POST /action Send Slack message, create GitHub issue
Resources GET /data Read a file, view database schema
Prompts Swagger/OpenAPI docs Templeates on how to optimally use tools

Transport Layer

MCP supports two transport methods:

Standard I/O — for MCP servers running on the same machine.

  • Communication via stdin/stdout
  • Fast and synchronous
  • Good for: Firebase, MySQL, Lighthouse, custom LGTM stacks
JSON
{
  "mcpServers": {
    "firebase": {
      "command": "npx",
      "args": ["-y", "firebase-tools@latest", "mcp"]
    },
    "mysql": {
      "command": "npx",
      "args": ["-y", "@bytebase/dbhub", "--transport", "stdio",
               "--dsn", "mysql://user:[email protected]:3306/mydb"]
    },
    "lighthouse": {
      "command": "npx",
      "args": ["lighthouse-mcp"]
    }
  }
}

Lifecycle: From Handshake to Operation

Initialization

The client sends an initialize request with the protocol version and its capabilities. The server responds with the capabilities it supports.

JSON
// Client -> Server
{
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-11-25",
    "capabilities": { "roots": { "listChanged": true } }
  }
}

Discovery

The client requests a list of available tools, resources, and prompts.

JSON
// Client -> Server
{ "method": "tools/list" }

// Server -> Client
{
  "tools": [
    {
      "name": "query_database",
      "description": "Execute SQL query",
      "inputSchema": { "type": "object", "properties": { "sql": { "type": "string" } } }
    }
  ]
}

Operation

The LLM calls tools based on conversational context.

JSON
// Client -> Server
{
  "method": "tools/call",
  "params": {
    "name": "query_database",
    "arguments": { "sql": "SELECT COUNT(*) FROM users WHERE active = true" }
  }
}

Building Your Own MCP Server

Here are minimal MCP server examples using TypeScript and Python:

Terminal
npm init -y
npm install @modelcontextprotocol/sdk zod
TypeScript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({
  name: "weather-server",
  version: "1.0.0",
});

// Define the tool
server.tool(
  "get_weather",
  "Get current weather for a city",
  { city: z.string().describe("City name") },
  async ({ city }) => {
    // Call a weather API
    const weather = await fetch(
      `https://api.weather.example.com/${city}`
    ).then((r) => r.json());

    return {
      content: [
        {
          type: "text",
          text: `Weather in ${city}: ${weather.temp}°C, ${weather.condition}`,
        },
      ],
    };
  }
);

// Run the server via stdio
const transport = new StdioServerTransport();
await server.connect(transport);
Don't Use console.log!

For stdio based servers, never use console.log() because it writes to stdout and will corrupt your JSON-RPC messages. Use console.error() or a logging library that writes exclusively to stderr.


Real-World Setup: My 11 MCP Servers

This isn't just theory — here is the MCP configuration I use daily in Gemini CLI and Claude Code:

graph TB
    subgraph STDIO["stdio (Local)"]
      S1[Firebase]
      S2[MySQL - dbhub]
      S3[LGTM - Grafana Stack]
      S4[Memory]
      S5[Sequential Thinking]
      S6[Serena - Code Understanding]
      S7[Lighthouse]
      S8[Word Document]
    end
    subgraph REMOTE["SSE / Remote"]
      R1[Mintlify Docs]
      R2[Context7]
      R3[Google Stitch]
    end
    style STDIO fill:#1e3a5f,color:#fff
    style REMOTE fill:#5f1e3a,color:#fff
Firebase — Deploy, Firestore, Auth right from AI

Using the official firebase-tools MCP. AI can instantly deploy, manage Firestore rules, inspect Auth users, and Cloud Functions — without opening the Firebase Console.

JSON
{
  "firebase": {
    "command": "npx",
    "args": ["-y", "firebase-tools@latest", "mcp"]
  }
}
MySQL (Bytebase dbhub) — Direct database queries

Using @bytebase/dbhub for MySQL access. AI can inspect schemas, execute queries, and analyze data straight from the chat.

JSON
{
  "mysql": {
    "command": "npx",
    "args": ["-y", "@bytebase/dbhub", "--transport", "stdio",
             "--dsn", "mysql://user:[email protected]:3306/mydb"]
  }
}
LGTM Stack — Grafana, Loki, Tempo, Mimir (Custom)

A custom-built MCP server for the observability stack. AI can query logs from Loki, traces from Tempo, metrics from Mimir, and visual dashboards from Grafana — all within a single conversation.

JSON
{
  "lgtm": {
    "command": "node",
    "args": ["/path/to/mcp-lgtm/dist/index.js"],
    "env": {
      "GRAFANA_URL": "http://localhost:3000",
      "LOKI_URL": "http://localhost:3100",
      "TEMPO_URL": "http://localhost:3200",
      "MIMIR_URL": "http://localhost:9009"
    }
  }
}
Memory — AI that can 'remember' across sessions

A persistent knowledge graph. AI saves critical context to a JSONL file, meaning your next session doesn't start from scratch.

JSON
{
  "memory": {
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-memory"],
    "env": {
      "MEMORY_FILE_PATH": "/path/to/memory.jsonl"
    }
  }
}
Context7 & Mintlify — Real-time documentation

Context7 provides up-to-date library context directly to the AI, so no more knowledge cutoff limits. Mintlify connects your self-hosted API documentation.

JSON
{
  "context7": {
    "serverUrl": "https://mcp.context7.com/mcp"
  },
  "mintlify": {
    "serverUrl": "https://docs.yourdomain.com/mcp"
  }
}
Lighthouse — Automated web performance audits

AI can run a Lighthouse audit and instantly analyze the results. Performance scores, accessibility issues, SEO recommendations — all in a conversation.

JSON
{
  "lighthouse": {
    "command": "npx",
    "args": ["lighthouse-mcp"]
  }
}
Sequential Thinking & Serena — Deeper AI thought

Sequential Thinking forces the AI to break down reasoning into structured steps. Serena gives deep code understanding — so AI navigates codebases with way more context than a simple grep.

JSON
{
  "sequential-thinking": {
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-sequential-thinking"]
  },
  "serena": {
    "command": "uvx",
    "args": ["--from", "git+https://github.com/oraios/serena",
             "serena", "start-mcp-server"]
  }
}
Google Stitch & Word — Connection to Google and Office

Google Stitch hooks you into the Google APIs ecosystem. Word Document Server lets AI create and edit Word documents — amazing for generating automated reports.

JSON
{
  "stitch": {
    "serverUrl": "https://stitch.googleapis.com/mcp",
    "headers": { "X-Goog-Api-Key": "YOUR_KEY" }
  },
  "word-document-server": {
    "command": "uvx",
    "args": ["--from", "office-word-mcp-server", "word_mcp_server"]
  }
}
The Lesson From This Setup

Notice the pattern: there are 3 classes of transport I use:

  • npx/uvx via stdio — for tools running locally (Firebase, MySQL, Lighthouse)
  • node custom script — for MCP servers I built myself (LGTM)
  • Remote serverUrl — for SaaS services (Context7, Mintlify, Google Stitch)

All three function simultaneously inside a single AI host. That is the raw power of the MCP standard.


Who Has Adopted It?

MCP isn't just an Anthropic standard — it has effectively become an industry standard:

Company Adoption
Anthropic Creator; native support in Claude Desktop & Claude Code
OpenAI Officially adopted March 2025; integrated in ChatGPT Desktop
Cursor The first AI IDE to fully support MCP
Block Integrates MCP apps into their Goose AI agent
Linux Foundation MCP donated to the Agentic AI Foundation (AAIF)
97 Million Downloads

As of December 2025, the MCP SDK hit 97 million monthly downloads across all programming languages. This isn't an experiment — it's a production-grade protocol.


When Should You Use MCP?


Security Considerations

MCP Security

MCP doesn't mean "open all the doors". Some critical security principles:

  • Principle of Least Privilege — Expose only the absolute necessary tools
  • Input Validation — Always validate LLM input before execution
  • Access Control — Limit which directories, databases, and APIs can be hit
  • User Confirmation — For destructive actions, demand explicit user confirmation
  • Audit Logging — Log all tool calls for strict accountability

Conclusion

MCP transforms how we integrate AI into the real world. Moving from custom-built, bespoke integrations tailored for every single permutation of an AI app and tool, we now have a single, universal protocol.

As an engineer, this feels like an inflection point similar to the advent of the REST API — a standard accelerating ecosystem growth simply because everybody is speaking the same language.

MCP isn't about making AI inherently smarter — it's about making AI fundamentally more useful.


References

Topics:#AI

Related stories

Engineering
Engineering
Integer to Roman: The Greedy Mapping That Always Shows Up in Interviews

Integer to Roman: The Greedy Mapping That Always Shows Up in Interviews

Breaking down the integer to Roman numeral conversion problem — from basic Roman numeral rules, the subtractive notation pitfalls (IV, IX, XL...), to a clean, interview-ready greedy O(1) solution. Complete with mapping table, step-by-step visualization, and why this approach is optimal given the 1-3999 constraint.
Faisal Affan
Faisal Affan
Published
Engineering
Best Time to Buy and Sell Stock: From Brute Force to One-Pass O(n)

Best Time to Buy and Sell Stock: From Brute Force to One-Pass O(n)

Master the classic coding interview problem 'Best Time to Buy and Sell Stock' with step-by-step explanation — from the naive brute force approach, recognizing patterns, to the optimal one-pass O(n) solution using sliding window / two-pointer technique. Complete with array visualization, complexity analysis, and the intuition behind every decision.
Faisal Affan
Faisal Affan
Published
Engineering
Services I've Handled — Full-Stack Engineering, Architecture & Product Strategy

Services I've Handled — Full-Stack Engineering, Architecture & Product Strategy

A comprehensive list of professional services I've delivered across multiple industries: IoT fleet management, fintech core banking integration, cyber insurance platforms, education technology, and enterprise digital transformation. Each service backed by real production systems still running today.
Faisal Affan
Faisal Affan
Published
Engineering
Portfolio Strategy by Career Level — Junior to CTO

Portfolio Strategy by Career Level — Junior to CTO

Your portfolio should reflect your seniority level, not just list every project you've touched. Junior engineers sell potential and fundamentals. Senior engineers sell depth and architecture. Staff engineers sell leverage. CTOs sell business outcomes. Here's exactly what to put in your portfolio at each level — with concrete examples and a universal format you can use today.
Faisal Affan
Faisal Affan
Published