Skip to content

MCP Server: Business Use Case for HeliosDB-Lite

Document ID: 18_MCP_SERVER.md Version: 1.0 Created: 2025-12-01 Category: AI Infrastructure / Developer Tools HeliosDB-Lite Version: 2.7.0+


Executive Summary

The Model Context Protocol (MCP) enables AI assistants like Claude to interact with external tools and data sources through a standardized interface. HeliosDB-Lite's MCP server transforms any Claude-powered application into a database-enabled assistant, allowing natural language database operations, semantic search, and time-travel queries without custom integration code. This enables developers to build AI assistants that can query, analyze, and manipulate data using conversational commands, reducing integration time from weeks to minutes.


Problem Being Solved

Core Problem Statement

AI assistants like Claude lack native database access capabilities. Developers must build custom tool integrations for every database operation, handle error cases, format results, and maintain synchronization between AI context and database state. This creates significant development overhead and limits AI assistant capabilities.

Root Cause Analysis

Factor Impact Current Workaround Limitation
No standardized DB interface Each integration custom-built Function calling + manual SQL High development cost
Context window limits Can't load full database Selective data fetching Manual pagination logic
Schema discovery AI doesn't know table structures Hardcoded schema descriptions Breaks on schema changes
Result formatting Raw SQL output unusable Custom formatters Maintenance burden

Business Impact Quantification

Metric Without MCP With MCP Server Improvement
Integration development time 2-4 weeks < 1 hour 100x faster
Maintenance overhead 20 hours/month 0 hours 100% reduction
AI query accuracy 70% (schema guessing) 95% (schema-aware) 25% improvement
Operations supported 5-10 (custom built) 50+ (comprehensive) 5-10x more capabilities

Who Suffers Most

  1. AI Application Developers: Spending weeks building custom database integrations for Claude/GPT assistants instead of focusing on core product features
  2. Enterprise AI Teams: Unable to give AI assistants access to business data without extensive security review of custom code
  3. Low-Code Builders: Want AI-powered data analysis but lack technical skills to build database integrations

Why Competitors Cannot Solve This

Technical Barriers

Competitor Category Limitation Root Cause Time to Match
Traditional DBs (PostgreSQL, MySQL) No MCP support Different architecture goals 6+ months
Cloud Vector DBs (Pinecone, Weaviate) Cloud-only, no SQL SaaS model 12+ months
SQLite No native MCP, no vectors Minimalist design 9+ months
Supabase Server-based, complex setup Cloud-first approach 6+ months

Architecture Requirements

To match HeliosDB-Lite's MCP capabilities, competitors would need:

  1. MCP Protocol Implementation: Full stdio/SSE transport with tool/resource/prompt support
  2. Schema Introspection Tools: Dynamic discovery of tables, columns, types, relationships
  3. Unified SQL + Vector: Natural language queries spanning structured and semantic data
  4. Time-Travel Integration: Point-in-time queries accessible through conversation
  5. Embedded Deployment: Zero-config local execution without network dependencies

Competitive Moat Analysis

Development Effort to Match:
├── MCP Protocol Implementation: 8 weeks (specification compliance)
├── Schema Discovery Tools: 4 weeks (introspection queries)
├── Natural Language SQL: 12 weeks (query generation + validation)
├── Vector Search Integration: 8 weeks (semantic MCP tools)
└── Total: 32 person-weeks (8 months)

Why They Won't:
├── MCP is Claude-ecosystem focused (competitors use different protocols)
├── Embedded + MCP is niche market segment
└── Requires tight integration with AI assistant patterns

HeliosDB-Lite Solution

Architecture Overview

┌─────────────────────────────────────────────────────────────┐
│                    Claude Desktop / API                      │
├─────────────────────────────────────────────────────────────┤
│                    MCP Protocol Layer                        │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐       │
│  │    Tools     │  │  Resources   │  │   Prompts    │       │
│  │ (Operations) │  │ (Data Views) │  │ (Templates)  │       │
│  └──────────────┘  └──────────────┘  └──────────────┘       │
├─────────────────────────────────────────────────────────────┤
│              HeliosDB-Lite MCP Server                        │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐       │
│  │  Query Tools │  │ Vector Tools │  │ Admin Tools  │       │
│  │  (SQL/CRUD)  │  │ (Semantic)   │  │ (Schema)     │       │
│  └──────────────┘  └──────────────┘  └──────────────┘       │
├─────────────────────────────────────────────────────────────┤
│              HeliosDB-Lite Engine (Embedded)                 │
└─────────────────────────────────────────────────────────────┘

Key Capabilities

Capability Description MCP Tool
Natural Language Queries Convert questions to SQL query, ask
Schema Discovery List tables, columns, types list_tables, describe_table
CRUD Operations Insert, update, delete data insert, update, delete
Vector Search Semantic similarity queries vector_search, find_similar
Time-Travel Query historical data states query_at_time, compare_versions
Analytics Aggregations, reports analyze, summarize

Concrete Examples with Code, Config & Architecture

Example 1: Claude Desktop Integration - Embedded Configuration

Scenario: Product manager wants to analyze customer data, run ad-hoc queries, and generate reports using natural language through Claude Desktop.

Architecture:

Claude Desktop App
    ↓ (MCP stdio transport)
HeliosDB-Lite MCP Server (local process)
Customer Database (./customers.db)

MCP Server Configuration (~/.config/claude/claude_desktop_config.json):

{
  "mcpServers": {
    "heliosdb": {
      "command": "heliosdb-mcp",
      "args": ["--database", "./data/customers.db"],
      "env": {
        "HELIOSDB_LOG_LEVEL": "info",
        "HELIOSDB_MAX_RESULTS": "1000",
        "HELIOSDB_ENABLE_WRITES": "true"
      }
    }
  }
}

HeliosDB MCP Server Configuration (heliosdb-mcp.toml):

[server]
name = "heliosdb-lite"
version = "2.7.0"
transport = "stdio"

[database]
path = "./data/customers.db"
memory_limit_mb = 512
enable_wal = true

[mcp]
enable_tools = true
enable_resources = true
enable_prompts = true

[mcp.tools]
# Query tools
query = true              # Execute SQL queries
ask = true                # Natural language to SQL
insert = true             # Insert records
update = true             # Update records
delete = true             # Delete records

# Schema tools
list_tables = true        # List all tables
describe_table = true     # Get table schema
list_columns = true       # Get column details

# Vector tools
vector_search = true      # Semantic search
find_similar = true       # Find similar records

# Time-travel tools
query_at_time = true      # Historical queries
compare_versions = true   # Diff between times

# Analytics tools
analyze = true            # Run analytics
summarize = true          # Data summaries

[mcp.resources]
# Expose database schema as resource
schema = true
# Expose sample data views
sample_data = true
# Expose query history
query_history = true

[mcp.prompts]
# Pre-built prompts for common tasks
data_analysis = true
report_generation = true
data_exploration = true

[security]
# Restrict dangerous operations
allow_drop_table = false
allow_truncate = false
max_rows_per_query = 10000
query_timeout_ms = 30000

MCP Tool Definitions (exposed to Claude):

{
  "tools": [
    {
      "name": "query",
      "description": "Execute a SQL query against the database. Returns results as formatted table.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "sql": {
            "type": "string",
            "description": "SQL query to execute"
          },
          "params": {
            "type": "array",
            "description": "Query parameters for prepared statement",
            "items": {"type": "string"}
          }
        },
        "required": ["sql"]
      }
    },
    {
      "name": "ask",
      "description": "Ask a natural language question about the data. Converts to SQL and returns results.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "question": {
            "type": "string",
            "description": "Natural language question about the data"
          },
          "table_hints": {
            "type": "array",
            "description": "Optional hints about which tables to query",
            "items": {"type": "string"}
          }
        },
        "required": ["question"]
      }
    },
    {
      "name": "list_tables",
      "description": "List all tables in the database with their row counts",
      "inputSchema": {
        "type": "object",
        "properties": {}
      }
    },
    {
      "name": "describe_table",
      "description": "Get schema details for a specific table including columns, types, and constraints",
      "inputSchema": {
        "type": "object",
        "properties": {
          "table_name": {
            "type": "string",
            "description": "Name of the table to describe"
          }
        },
        "required": ["table_name"]
      }
    },
    {
      "name": "vector_search",
      "description": "Search for semantically similar records using vector embeddings",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Search query text"
          },
          "table": {
            "type": "string",
            "description": "Table with vector column to search"
          },
          "limit": {
            "type": "integer",
            "description": "Maximum results to return",
            "default": 10
          },
          "filters": {
            "type": "object",
            "description": "Additional SQL filters"
          }
        },
        "required": ["query", "table"]
      }
    },
    {
      "name": "query_at_time",
      "description": "Query the database as it existed at a specific point in time (time-travel)",
      "inputSchema": {
        "type": "object",
        "properties": {
          "sql": {
            "type": "string",
            "description": "SQL query to execute"
          },
          "timestamp": {
            "type": "string",
            "description": "ISO 8601 timestamp for historical query"
          }
        },
        "required": ["sql", "timestamp"]
      }
    },
    {
      "name": "analyze",
      "description": "Run analytics on a table: distributions, correlations, outliers",
      "inputSchema": {
        "type": "object",
        "properties": {
          "table": {
            "type": "string",
            "description": "Table to analyze"
          },
          "columns": {
            "type": "array",
            "description": "Specific columns to analyze",
            "items": {"type": "string"}
          },
          "analysis_type": {
            "type": "string",
            "enum": ["distribution", "correlation", "outliers", "summary"],
            "description": "Type of analysis to perform"
          }
        },
        "required": ["table"]
      }
    }
  ]
}

Example Conversation with Claude:

User: What are our top 10 customers by revenue this quarter?

Claude: I'll query the database to find the top customers by revenue.

[Uses tool: query]
{
  "sql": "SELECT c.name, c.email, SUM(o.amount) as total_revenue
          FROM customers c
          JOIN orders o ON c.id = o.customer_id
          WHERE o.created_at >= date_trunc('quarter', CURRENT_DATE)
          GROUP BY c.id, c.name, c.email
          ORDER BY total_revenue DESC
          LIMIT 10"
}

Here are your top 10 customers by Q4 revenue:

| Rank | Customer | Email | Revenue |
|------|----------|-------|---------|
| 1 | Acme Corp | sales@acme.com | $125,430 |
| 2 | TechStart Inc | orders@techstart.io | $98,200 |
...

User: Show me customers similar to Acme Corp

Claude: I'll search for customers with similar profiles to Acme Corp.

[Uses tool: vector_search]
{
  "query": "Large enterprise, manufacturing sector, high-volume orders",
  "table": "customers",
  "limit": 5,
  "filters": {"id": {"$ne": "acme-corp-id"}}
}

Found 5 customers with similar profiles to Acme Corp:
...

Results: | Metric | Before (Custom Integration) | After (MCP) | Improvement | |--------|------------------------------|-------------|-------------| | Integration time | 3 weeks | 30 minutes | 100x faster | | Query accuracy | 75% | 95% | 20% improvement | | Operations supported | 8 | 50+ | 6x more |


Example 2: AI Data Analyst - Language Binding Integration (Python)

Scenario: Data science team wants Claude to act as an AI data analyst, exploring datasets, generating visualizations, and providing insights through conversation.

Python MCP Server Implementation:

import asyncio
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent, Resource, Prompt
import heliosdb_lite
from typing import Any
import json

class HeliosDBMCPServer:
    """MCP Server for HeliosDB-Lite database operations."""

    def __init__(self, db_path: str):
        self.db = heliosdb_lite.connect(db_path)
        self.server = Server("heliosdb-lite")
        self._register_tools()
        self._register_resources()
        self._register_prompts()

    def _register_tools(self):
        """Register MCP tools for database operations."""

        @self.server.tool()
        async def query(sql: str, params: list = None) -> str:
            """Execute a SQL query and return formatted results."""
            try:
                results = self.db.execute(sql, params or [])
                return self._format_results(results)
            except Exception as e:
                return f"Error: {str(e)}"

        @self.server.tool()
        async def ask(question: str, table_hints: list = None) -> str:
            """Convert natural language question to SQL and execute."""
            try:
                # Get schema context
                schema = self._get_schema_context(table_hints)

                # Generate SQL from question (simplified - would use LLM in practice)
                sql = self._question_to_sql(question, schema)

                results = self.db.execute(sql)
                return f"Query: {sql}\n\nResults:\n{self._format_results(results)}"
            except Exception as e:
                return f"Error: {str(e)}"

        @self.server.tool()
        async def list_tables() -> str:
            """List all tables in the database."""
            results = self.db.execute("""
                SELECT table_name,
                       (SELECT COUNT(*) FROM information_schema.columns
                        WHERE table_name = t.table_name) as column_count
                FROM information_schema.tables t
                WHERE table_schema = 'public'
                ORDER BY table_name
            """)
            return self._format_results(results)

        @self.server.tool()
        async def describe_table(table_name: str) -> str:
            """Get detailed schema for a table."""
            columns = self.db.execute("""
                SELECT column_name, data_type, is_nullable, column_default
                FROM information_schema.columns
                WHERE table_name = $1
                ORDER BY ordinal_position
            """, [table_name])

            constraints = self.db.execute("""
                SELECT constraint_name, constraint_type
                FROM information_schema.table_constraints
                WHERE table_name = $1
            """, [table_name])

            sample = self.db.execute(f"SELECT * FROM {table_name} LIMIT 3")

            return f"""
Table: {table_name}

Columns:
{self._format_results(columns)}

Constraints:
{self._format_results(constraints)}

Sample Data:
{self._format_results(sample)}
"""

        @self.server.tool()
        async def vector_search(
            query: str,
            table: str,
            vector_column: str = "embedding",
            limit: int = 10,
            filters: dict = None
        ) -> str:
            """Semantic search using vector embeddings."""
            try:
                # Generate query embedding
                query_embedding = self._get_embedding(query)

                # Build filter clause
                where_clause = ""
                params = [query_embedding, limit]
                if filters:
                    conditions = []
                    for key, value in filters.items():
                        params.append(value)
                        conditions.append(f"{key} = ${len(params)}")
                    where_clause = "WHERE " + " AND ".join(conditions)

                sql = f"""
                    SELECT *, 1 - ({vector_column} <=> $1) as similarity
                    FROM {table}
                    {where_clause}
                    ORDER BY {vector_column} <=> $1
                    LIMIT $2
                """

                results = self.db.execute(sql, params)
                return self._format_results(results)
            except Exception as e:
                return f"Error: {str(e)}"

        @self.server.tool()
        async def query_at_time(sql: str, timestamp: str) -> str:
            """Execute query against historical database state."""
            try:
                # Modify query for time-travel
                time_travel_sql = sql.replace(
                    "FROM ",
                    f"FROM ... FOR SYSTEM_TIME AS OF '{timestamp}' "
                )
                results = self.db.execute(time_travel_sql)
                return f"Results as of {timestamp}:\n{self._format_results(results)}"
            except Exception as e:
                return f"Error: {str(e)}"

        @self.server.tool()
        async def insert(table: str, data: dict) -> str:
            """Insert a record into a table."""
            try:
                columns = ", ".join(data.keys())
                placeholders = ", ".join([f"${i+1}" for i in range(len(data))])
                values = list(data.values())

                result = self.db.execute(
                    f"INSERT INTO {table} ({columns}) VALUES ({placeholders}) RETURNING *",
                    values
                )
                return f"Inserted: {self._format_results(result)}"
            except Exception as e:
                return f"Error: {str(e)}"

        @self.server.tool()
        async def analyze(
            table: str,
            columns: list = None,
            analysis_type: str = "summary"
        ) -> str:
            """Analyze data in a table."""
            try:
                if analysis_type == "summary":
                    return await self._analyze_summary(table, columns)
                elif analysis_type == "distribution":
                    return await self._analyze_distribution(table, columns)
                elif analysis_type == "correlation":
                    return await self._analyze_correlation(table, columns)
                elif analysis_type == "outliers":
                    return await self._analyze_outliers(table, columns)
            except Exception as e:
                return f"Error: {str(e)}"

    def _register_resources(self):
        """Register MCP resources for data access."""

        @self.server.resource("schema://database")
        async def get_schema() -> str:
            """Get complete database schema."""
            tables = self.db.execute("""
                SELECT table_name FROM information_schema.tables
                WHERE table_schema = 'public'
            """)

            schema_text = "# Database Schema\n\n"
            for table in tables:
                table_name = table['table_name']
                columns = self.db.execute("""
                    SELECT column_name, data_type, is_nullable
                    FROM information_schema.columns
                    WHERE table_name = $1
                    ORDER BY ordinal_position
                """, [table_name])

                schema_text += f"## {table_name}\n"
                for col in columns:
                    nullable = "NULL" if col['is_nullable'] == 'YES' else "NOT NULL"
                    schema_text += f"- {col['column_name']}: {col['data_type']} {nullable}\n"
                schema_text += "\n"

            return schema_text

        @self.server.resource("data://{table}/sample")
        async def get_sample(table: str) -> str:
            """Get sample data from a table."""
            results = self.db.execute(f"SELECT * FROM {table} LIMIT 10")
            return self._format_results(results)

    def _register_prompts(self):
        """Register MCP prompts for common tasks."""

        @self.server.prompt("data-exploration")
        async def data_exploration_prompt() -> list:
            """Prompt for exploring a new dataset."""
            return [
                {"role": "user", "content": """
I want to explore this database. Please:
1. List all available tables
2. For each table, describe its schema and show sample data
3. Identify potential relationships between tables
4. Suggest interesting queries or analyses I could run
"""}
            ]

        @self.server.prompt("generate-report")
        async def report_prompt(topic: str) -> list:
            """Prompt for generating a data report."""
            return [
                {"role": "user", "content": f"""
Generate a comprehensive report about: {topic}

Include:
1. Key metrics and KPIs
2. Trends over time
3. Notable patterns or anomalies
4. Recommendations based on the data
"""}
            ]

    def _format_results(self, results: list) -> str:
        """Format query results as markdown table."""
        if not results:
            return "No results"

        headers = list(results[0].keys())
        rows = [[str(row[h]) for h in headers] for row in results]

        # Calculate column widths
        widths = [max(len(h), max(len(r[i]) for r in rows)) for i, h in enumerate(headers)]

        # Build table
        header_row = " | ".join(h.ljust(w) for h, w in zip(headers, widths))
        separator = "-|-".join("-" * w for w in widths)
        data_rows = "\n".join(
            " | ".join(c.ljust(w) for c, w in zip(row, widths))
            for row in rows[:100]  # Limit rows
        )

        return f"{header_row}\n{separator}\n{data_rows}"

    async def run(self):
        """Run the MCP server."""
        async with stdio_server() as (read_stream, write_stream):
            await self.server.run(read_stream, write_stream)


# Entry point
if __name__ == "__main__":
    import sys
    db_path = sys.argv[1] if len(sys.argv) > 1 else "./data.db"
    server = HeliosDBMCPServer(db_path)
    asyncio.run(server.run())

Architecture Pattern:

┌─────────────────────────────────────────┐
│     Claude API / Claude Desktop          │
├─────────────────────────────────────────┤
│  MCP Client (stdio/SSE transport)        │
├─────────────────────────────────────────┤
│  HeliosDBMCPServer (Python)              │
│  - Tool handlers (query, analyze, etc.)  │
│  - Resource providers (schema, samples)  │
│  - Prompt templates                      │
├─────────────────────────────────────────┤
│  HeliosDB-Lite Python Bindings           │
├─────────────────────────────────────────┤
│  In-Process Database Engine              │
└─────────────────────────────────────────┘

Results: - Tool invocations: <50ms average - Schema discovery: Automatic, always current - Query accuracy: 95%+ with schema context - Supported operations: 50+ via 12 core tools


Example 3: Enterprise Assistant - Infrastructure & Container Deployment

Scenario: Enterprise deploys Claude-powered business assistant that needs access to CRM, sales, and support databases through MCP.

Docker Deployment (Dockerfile):

FROM rust:1.75-slim as builder

WORKDIR /app
COPY . .

RUN cargo build --release --bin heliosdb-mcp-server

FROM debian:bookworm-slim

RUN apt-get update && apt-get install -y \
    ca-certificates \
    && rm -rf /var/lib/apt/lists/*

COPY --from=builder /app/target/release/heliosdb-mcp-server /usr/local/bin/

RUN mkdir -p /data /config

VOLUME ["/data", "/config"]

ENTRYPOINT ["heliosdb-mcp-server"]
CMD ["--config", "/config/mcp-server.toml"]

Docker Compose (docker-compose.yml):

version: '3.8'

services:
  heliosdb-mcp:
    build: .
    image: heliosdb-mcp-server:latest
    container_name: enterprise-mcp-server

    volumes:
      - ./data:/data
      - ./config:/config:ro

    environment:
      HELIOSDB_LOG_LEVEL: info
      MCP_TRANSPORT: sse
      MCP_PORT: "8080"
      HELIOSDB_DATABASE: "/data/enterprise.db"

    ports:
      - "8080:8080"   # SSE endpoint for Claude API

    restart: unless-stopped

    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 2G

    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 5s
      retries: 3

  # Optional: Admin UI
  mcp-admin:
    image: heliosdb-mcp-admin:latest
    container_name: mcp-admin

    ports:
      - "3000:3000"

    environment:
      MCP_SERVER_URL: "http://heliosdb-mcp:8080"

    depends_on:
      - heliosdb-mcp

volumes:
  enterprise_data:
    driver: local

networks:
  default:
    name: enterprise-mcp

Enterprise MCP Configuration (mcp-server.toml):

[server]
name = "enterprise-heliosdb"
version = "2.7.0"
transport = "sse"           # Server-Sent Events for Claude API
host = "0.0.0.0"
port = 8080

[database]
path = "/data/enterprise.db"
memory_limit_mb = 2048
enable_wal = true

[mcp.tools]
# Read operations (always enabled)
query = true
list_tables = true
describe_table = true
vector_search = true
analyze = true

# Write operations (controlled by role)
insert = true
update = true
delete = false              # Disabled for safety

# Admin operations (restricted)
create_table = false
alter_table = false
drop_table = false

[mcp.security]
# Role-based access control
enable_rbac = true
default_role = "analyst"

[mcp.security.roles.analyst]
allowed_tables = ["customers", "orders", "products", "support_tickets"]
allowed_operations = ["query", "list_tables", "describe_table", "analyze"]
max_rows = 10000
allow_writes = false

[mcp.security.roles.data_engineer]
allowed_tables = ["*"]
allowed_operations = ["query", "list_tables", "describe_table", "insert", "update", "analyze"]
max_rows = 100000
allow_writes = true

[mcp.security.roles.admin]
allowed_tables = ["*"]
allowed_operations = ["*"]
max_rows = -1               # Unlimited
allow_writes = true

[mcp.audit]
enabled = true
log_queries = true
log_results = false         # Don't log sensitive data
log_path = "/data/audit.log"

[mcp.resources]
# Expose curated data views
schema = true
metrics_dashboard = true
kpi_summary = true

[mcp.prompts]
sales_analysis = true
customer_360 = true
support_insights = true

Claude API Integration (TypeScript):

import Anthropic from '@anthropic-ai/sdk';

const anthropic = new Anthropic();

async function enterpriseAssistant(userQuery: string, userRole: string) {
  // Connect to MCP server with role-based token
  const mcpEndpoint = `https://mcp.enterprise.com/sse?role=${userRole}`;

  const response = await anthropic.messages.create({
    model: "claude-sonnet-4-20250514",
    max_tokens: 4096,
    system: `You are an enterprise data assistant with access to the company database.
             Use the available tools to answer questions about customers, orders, and sales.
             Always respect data access policies and don't expose sensitive information.`,
    messages: [
      { role: "user", content: userQuery }
    ],
    tools: [
      // Tools are discovered from MCP server
    ],
    tool_choice: { type: "auto" },
    // MCP connection config
    mcp_servers: [{
      name: "enterprise-heliosdb",
      transport: "sse",
      url: mcpEndpoint
    }]
  });

  return response;
}

// Usage
const result = await enterpriseAssistant(
  "What's our customer churn rate this quarter compared to last quarter?",
  "analyst"
);

Results: - Deployment time: < 1 hour - Concurrent users: 100+ via SSE - Query latency: <100ms including Claude roundtrip - Audit compliance: Full query logging


Example 4: AI Coding Assistant - Microservices Integration (Rust)

Scenario: IDE extension uses Claude as a coding assistant that needs to query project databases, understand schemas, and help with database-related code.

Rust MCP Server (src/main.rs):

use mcp_server::{Server, Tool, Resource, Transport};
use heliosdb_lite::Connection;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use tokio::sync::RwLock;

#[derive(Clone)]
pub struct CodingAssistantMCP {
    connections: Arc<RwLock<HashMap<String, Connection>>>,
}

impl CodingAssistantMCP {
    pub fn new() -> Self {
        CodingAssistantMCP {
            connections: Arc::new(RwLock::new(HashMap::new())),
        }
    }

    /// Connect to a project database
    async fn connect(&self, project_path: &str, db_path: &str) -> Result<String, String> {
        let full_path = format!("{}/{}", project_path, db_path);
        let conn = Connection::open(&full_path).map_err(|e| e.to_string())?;

        let mut connections = self.connections.write().await;
        connections.insert(project_path.to_string(), conn);

        Ok(format!("Connected to database: {}", full_path))
    }

    /// Generate model code from table schema
    async fn generate_model(&self, project: &str, table: &str, language: &str) -> Result<String, String> {
        let connections = self.connections.read().await;
        let conn = connections.get(project)
            .ok_or("Project not connected")?;

        let columns = conn.query(
            "SELECT column_name, data_type, is_nullable
             FROM information_schema.columns
             WHERE table_name = $1",
            &[&table],
        ).map_err(|e| e.to_string())?;

        match language {
            "rust" => Ok(self.generate_rust_model(table, &columns)),
            "python" => Ok(self.generate_python_model(table, &columns)),
            "typescript" => Ok(self.generate_typescript_model(table, &columns)),
            _ => Err("Unsupported language".to_string()),
        }
    }

    fn generate_rust_model(&self, table: &str, columns: &[Row]) -> String {
        let struct_name = to_pascal_case(table);
        let mut code = format!(
            r#"use serde::{{Deserialize, Serialize}};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct {} {{
"#, struct_name);

        for col in columns {
            let col_name = col.get::<String>("column_name");
            let col_type = self.sql_to_rust_type(
                col.get::<String>("data_type").as_str(),
                col.get::<String>("is_nullable").as_str() == "YES"
            );
            code.push_str(&format!("    pub {}: {},\n", to_snake_case(&col_name), col_type));
        }

        code.push_str("}\n");
        code
    }

    fn generate_typescript_model(&self, table: &str, columns: &[Row]) -> String {
        let interface_name = to_pascal_case(table);
        let mut code = format!("export interface {} {{\n", interface_name);

        for col in columns {
            let col_name = col.get::<String>("column_name");
            let col_type = self.sql_to_ts_type(col.get::<String>("data_type").as_str());
            let optional = if col.get::<String>("is_nullable") == "YES" { "?" } else { "" };
            code.push_str(&format!("  {}{}: {};\n", col_name, optional, col_type));
        }

        code.push_str("}\n");
        code
    }

    /// Generate SQL migration from schema diff
    async fn generate_migration(
        &self,
        project: &str,
        from_time: &str,
        to_time: &str,
    ) -> Result<String, String> {
        let connections = self.connections.read().await;
        let conn = connections.get(project)
            .ok_or("Project not connected")?;

        // Get schema at both times using time-travel
        let old_schema = self.get_schema_at_time(conn, from_time)?;
        let new_schema = self.get_schema_at_time(conn, to_time)?;

        // Generate migration SQL
        let migration = self.diff_schemas(&old_schema, &new_schema);
        Ok(migration)
    }

    /// Explain query execution plan
    async fn explain_query(&self, project: &str, sql: &str) -> Result<String, String> {
        let connections = self.connections.read().await;
        let conn = connections.get(project)
            .ok_or("Project not connected")?;

        let plan = conn.query(&format!("EXPLAIN ANALYZE {}", sql), &[])
            .map_err(|e| e.to_string())?;

        Ok(self.format_explain_plan(&plan))
    }

    /// Suggest index for slow query
    async fn suggest_index(&self, project: &str, sql: &str) -> Result<String, String> {
        let connections = self.connections.read().await;
        let conn = connections.get(project)
            .ok_or("Project not connected")?;

        let plan = conn.query(&format!("EXPLAIN ANALYZE {}", sql), &[])
            .map_err(|e| e.to_string())?;

        // Analyze plan for sequential scans
        let suggestions = self.analyze_for_indexes(&plan, sql);
        Ok(suggestions)
    }
}

// Register MCP tools
fn register_tools(server: &mut Server, mcp: CodingAssistantMCP) {
    server.register_tool(Tool {
        name: "connect_database".to_string(),
        description: "Connect to a project's database".to_string(),
        handler: move |params| {
            let project = params.get("project").unwrap().as_str().unwrap();
            let db_path = params.get("db_path").unwrap().as_str().unwrap();
            Box::pin(mcp.clone().connect(project, db_path))
        },
        schema: serde_json::json!({
            "type": "object",
            "properties": {
                "project": {"type": "string", "description": "Project root path"},
                "db_path": {"type": "string", "description": "Relative path to database"}
            },
            "required": ["project", "db_path"]
        }),
    });

    server.register_tool(Tool {
        name: "generate_model".to_string(),
        description: "Generate model/struct code from database table schema".to_string(),
        handler: move |params| {
            let project = params.get("project").unwrap().as_str().unwrap();
            let table = params.get("table").unwrap().as_str().unwrap();
            let language = params.get("language").unwrap_or(&json!("rust")).as_str().unwrap();
            Box::pin(mcp.clone().generate_model(project, table, language))
        },
        schema: serde_json::json!({
            "type": "object",
            "properties": {
                "project": {"type": "string"},
                "table": {"type": "string"},
                "language": {"type": "string", "enum": ["rust", "python", "typescript"]}
            },
            "required": ["project", "table"]
        }),
    });

    server.register_tool(Tool {
        name: "explain_query".to_string(),
        description: "Get execution plan for a SQL query".to_string(),
        handler: move |params| {
            let project = params.get("project").unwrap().as_str().unwrap();
            let sql = params.get("sql").unwrap().as_str().unwrap();
            Box::pin(mcp.clone().explain_query(project, sql))
        },
        schema: serde_json::json!({
            "type": "object",
            "properties": {
                "project": {"type": "string"},
                "sql": {"type": "string"}
            },
            "required": ["project", "sql"]
        }),
    });

    server.register_tool(Tool {
        name: "suggest_index".to_string(),
        description: "Suggest database indexes to optimize a slow query".to_string(),
        handler: move |params| {
            let project = params.get("project").unwrap().as_str().unwrap();
            let sql = params.get("sql").unwrap().as_str().unwrap();
            Box::pin(mcp.clone().suggest_index(project, sql))
        },
        schema: serde_json::json!({
            "type": "object",
            "properties": {
                "project": {"type": "string"},
                "sql": {"type": "string"}
            },
            "required": ["project", "sql"]
        }),
    });
}

#[tokio::main]
async fn main() {
    let mcp = CodingAssistantMCP::new();
    let mut server = Server::new("heliosdb-coding-assistant", "1.0.0");

    register_tools(&mut server, mcp);

    server.run(Transport::Stdio).await;
}

IDE Extension Integration:

// VS Code extension using MCP
import * as vscode from 'vscode';
import { Client } from '@modelcontextprotocol/sdk/client';

export async function activate(context: vscode.ExtensionContext) {
  // Start MCP server
  const mcpClient = new Client({
    name: "vscode-heliosdb",
    version: "1.0.0"
  });

  await mcpClient.connect({
    command: "heliosdb-mcp-server",
    args: ["--project", vscode.workspace.rootPath]
  });

  // Register commands
  context.subscriptions.push(
    vscode.commands.registerCommand('heliosdb.generateModel', async () => {
      const table = await vscode.window.showInputBox({
        prompt: 'Enter table name'
      });

      const result = await mcpClient.callTool('generate_model', {
        project: vscode.workspace.rootPath,
        table: table,
        language: 'typescript'
      });

      // Insert generated code at cursor
      const editor = vscode.window.activeTextEditor;
      if (editor) {
        editor.edit(editBuilder => {
          editBuilder.insert(editor.selection.active, result.content);
        });
      }
    })
  );
}

Results: - Model generation: <100ms - Query explanation: <200ms - Index suggestions: <500ms - Developer productivity: 50% faster database code


Example 5: Mobile AI Assistant - Edge Computing Deployment

Scenario: Mobile app includes AI assistant that needs local database access on device, working offline without cloud dependencies.

Edge Device Configuration:

[server]
name = "mobile-heliosdb"
version = "2.7.0"
transport = "local"         # In-process, no network

[database]
path = "/var/mobile/app.db"
memory_limit_mb = 128
page_size = 4096
enable_wal = true

[mcp]
enable_tools = true
enable_resources = true
enable_prompts = false      # Prompts handled by app

[mcp.tools]
# Read-only on mobile by default
query = true
list_tables = true
describe_table = true
vector_search = true
analyze = false             # Too heavy for mobile

# Limited writes
insert = true
update = true
delete = false

[mcp.limits]
max_query_time_ms = 1000
max_results = 100
max_concurrent_queries = 2

[offline]
enabled = true
cache_schema = true
preload_tables = ["user_preferences", "cached_data"]

Mobile MCP Integration (Swift):

import Foundation
import HeliosDBLite

class LocalMCPServer {
    private let db: HeliosDB
    private var tools: [String: MCPTool] = [:]

    init(dbPath: String) throws {
        self.db = try HeliosDB(path: dbPath)
        registerTools()
    }

    private func registerTools() {
        // Query tool
        tools["query"] = MCPTool(
            name: "query",
            description: "Execute SQL query on local database",
            handler: { [weak self] params in
                guard let sql = params["sql"] as? String else {
                    return MCPResult.error("Missing SQL parameter")
                }
                return self?.executeQuery(sql) ?? MCPResult.error("Server not available")
            }
        )

        // Vector search for local semantic queries
        tools["local_search"] = MCPTool(
            name: "local_search",
            description: "Semantic search on locally cached data",
            handler: { [weak self] params in
                guard let query = params["query"] as? String else {
                    return MCPResult.error("Missing query")
                }
                let table = params["table"] as? String ?? "cached_content"
                let limit = params["limit"] as? Int ?? 10
                return self?.vectorSearch(query: query, table: table, limit: limit)
                    ?? MCPResult.error("Server not available")
            }
        )

        // User preferences (offline-first)
        tools["get_preferences"] = MCPTool(
            name: "get_preferences",
            description: "Get user preferences from local database",
            handler: { [weak self] params in
                let category = params["category"] as? String
                return self?.getPreferences(category: category)
                    ?? MCPResult.error("Server not available")
            }
        )

        tools["set_preference"] = MCPTool(
            name: "set_preference",
            description: "Save user preference locally",
            handler: { [weak self] params in
                guard let key = params["key"] as? String,
                      let value = params["value"] else {
                    return MCPResult.error("Missing key or value")
                }
                return self?.setPreference(key: key, value: value)
                    ?? MCPResult.error("Server not available")
            }
        )
    }

    func handleToolCall(name: String, params: [String: Any]) -> MCPResult {
        guard let tool = tools[name] else {
            return MCPResult.error("Unknown tool: \(name)")
        }
        return tool.handler(params)
    }

    private func executeQuery(_ sql: String) -> MCPResult {
        do {
            let results = try db.execute(sql)
            return MCPResult.success(formatResults(results))
        } catch {
            return MCPResult.error(error.localizedDescription)
        }
    }

    private func vectorSearch(query: String, table: String, limit: Int) -> MCPResult {
        do {
            // Generate embedding locally using on-device model
            let embedding = try LocalEmbedder.shared.embed(query)

            let results = try db.execute("""
                SELECT *, 1 - (embedding <=> $1) as similarity
                FROM \(table)
                WHERE embedding IS NOT NULL
                ORDER BY embedding <=> $1
                LIMIT $2
            """, [embedding, limit])

            return MCPResult.success(formatResults(results))
        } catch {
            return MCPResult.error(error.localizedDescription)
        }
    }

    private func getPreferences(category: String?) -> MCPResult {
        do {
            let sql: String
            let params: [Any]

            if let cat = category {
                sql = "SELECT key, value FROM user_preferences WHERE category = $1"
                params = [cat]
            } else {
                sql = "SELECT category, key, value FROM user_preferences"
                params = []
            }

            let results = try db.execute(sql, params)
            return MCPResult.success(formatResults(results))
        } catch {
            return MCPResult.error(error.localizedDescription)
        }
    }

    private func setPreference(key: String, value: Any) -> MCPResult {
        do {
            try db.execute("""
                INSERT INTO user_preferences (key, value, updated_at)
                VALUES ($1, $2, datetime('now'))
                ON CONFLICT (key) DO UPDATE SET value = $2, updated_at = datetime('now')
            """, [key, value])
            return MCPResult.success("Preference saved")
        } catch {
            return MCPResult.error(error.localizedDescription)
        }
    }
}

// Mobile AI Assistant using local MCP
class MobileAssistant {
    private let mcpServer: LocalMCPServer
    private let llm: OnDeviceLLM  // Local small model

    init() throws {
        let dbPath = FileManager.default.applicationSupportDirectory
            .appendingPathComponent("app.db").path
        self.mcpServer = try LocalMCPServer(dbPath: dbPath)
        self.llm = try OnDeviceLLM(model: "phi-3-mini")
    }

    func ask(_ question: String) async -> String {
        // Determine which tools to use
        let toolPlan = await llm.planTools(question: question, availableTools: [
            "query", "local_search", "get_preferences"
        ])

        var context = ""

        // Execute tool calls
        for toolCall in toolPlan.toolCalls {
            let result = mcpServer.handleToolCall(
                name: toolCall.name,
                params: toolCall.params
            )
            context += "Tool \(toolCall.name) result:\n\(result.content)\n\n"
        }

        // Generate response
        let response = await llm.generate(
            system: "You are a helpful mobile assistant with access to the user's local data.",
            context: context,
            question: question
        )

        return response
    }
}

Mobile Architecture:

┌───────────────────────────────────┐
│    iOS/Android Mobile App          │
├───────────────────────────────────┤
│   MobileAssistant UI               │
├───────────────────────────────────┤
│   On-Device LLM (Phi-3 Mini)       │
├───────────────────────────────────┤
│   LocalMCPServer                   │
│   - In-process tool handling       │
│   - No network required            │
├───────────────────────────────────┤
│   HeliosDB-Lite (Embedded)         │
│   - Local embeddings               │
│   - User data persistence          │
└───────────────────────────────────┘

Results: - Tool execution: <50ms on-device - Full offline operation - Privacy-preserving (no data leaves device) - Battery efficient (no network)


Market Audience

Primary Segments

Segment 1: AI Application Developers

Attribute Details
Company Size 2-200 employees
Industry SaaS, AI/ML, Developer Tools
Pain Points Integration time, maintenance, tool limitations
Decision Makers CTO, Engineering Lead
Budget Range $5K-$50K tooling budget
Deployment Model Embedded / Desktop / Container

Value Proposition: Add database capabilities to Claude assistants in minutes, not weeks.

Segment 2: Enterprise IT Teams

Attribute Details
Company Size 1,000-50,000 employees
Industry Finance, Healthcare, Manufacturing
Pain Points Security, audit, access control
Decision Makers CTO, Chief AI Officer
Budget Range $100K-$1M AI infrastructure
Deployment Model On-premise / Private cloud

Value Proposition: Secure, auditable AI assistant database access with role-based permissions.

Segment 3: Mobile/Edge AI Teams

Attribute Details
Company Size 10-500 employees
Industry Consumer apps, IoT, Healthcare
Pain Points Offline operation, privacy, latency
Decision Makers Mobile Lead, Product Manager
Budget Range $20K-$200K per product
Deployment Model Mobile / Edge / Embedded

Value Proposition: On-device AI assistant with local database access, zero cloud dependency.

Buyer Personas

Persona Title Pain Point Buying Trigger Message
Builder Bob Full-Stack Developer 3 weeks to integrate DB with Claude Deadline pressure "MCP integration in 30 minutes"
Security Sam Enterprise Architect Can't approve custom integrations Compliance audit "Auditable, RBAC-enabled MCP server"
Privacy Paula Mobile PM Users want offline AI assistant Privacy regulations "On-device MCP, no cloud required"

Technical Advantages

Why HeliosDB-Lite Excels

Aspect HeliosDB-Lite MCP Custom Integration Other MCP DBs
Setup Time 30 minutes 2-4 weeks 1-2 days
Tools Included 50+ Build from scratch 10-20
Vector Search Native Separate integration Limited
Time-Travel Built-in Not available Not available
Offline Support Full Varies Rare

Performance Characteristics

Operation Latency Throughput Memory
Tool invocation <10ms 1000/sec Minimal
Query execution <50ms 100/sec Variable
Schema discovery <5ms N/A Cached
Vector search <20ms 50/sec Index size

Adoption Strategy

Phase 1: Local Development (Week 1)

Target: Developers testing MCP integration

Tactics: - npm install heliosdb-mcp or cargo install heliosdb-mcp - Add to Claude Desktop config - Test with sample database

Success Metrics: - Working in < 1 hour - All tools functional - Schema discovered correctly

Phase 2: Application Integration (Weeks 2-4)

Target: Production Claude applications

Tactics: - Deploy MCP server with application - Configure security/RBAC - Monitor tool usage

Success Metrics: - 99% tool success rate - Query latency < 200ms - Zero security issues

Phase 3: Enterprise Rollout (Weeks 5+)

Target: Organization-wide AI assistants

Tactics: - Deploy centralized MCP infrastructure - Integrate with SSO/audit systems - Train users on AI assistant capabilities

Success Metrics: - 100+ users active - Audit compliance achieved - Positive user feedback


Key Success Metrics

Technical KPIs

Metric Target Measurement Method
Tool invocation latency < 50ms P95 MCP server metrics
Query success rate > 99% Error tracking
Schema accuracy 100% Automated tests

Business KPIs

Metric Target Measurement Method
Integration time < 2 hours Developer surveys
Tool coverage 50+ operations Feature tracking
Developer satisfaction > 4.5/5 NPS surveys

Conclusion

The Model Context Protocol represents a paradigm shift in how AI assistants interact with external systems. Instead of building custom integrations for every database operation, MCP provides a standardized interface that Claude understands natively. HeliosDB-Lite's MCP server brings this capability to embedded databases, enabling AI-powered data analysis, natural language queries, and intelligent assistance without cloud dependencies.

For developers, this means shipping AI-enabled products in days instead of months. For enterprises, it means secure, auditable AI assistant capabilities with proper access controls. For mobile and edge applications, it means on-device AI assistants that work offline with full database capabilities.

The market opportunity is every Claude-powered application that needs database access - from coding assistants to business analysts to mobile apps. Teams adopting HeliosDB-Lite's MCP server gain the fastest path to AI-integrated database capabilities while maintaining the flexibility and control of an embedded solution.


References

  1. Model Context Protocol Specification: https://modelcontextprotocol.io/
  2. Claude MCP Documentation: https://docs.anthropic.com/claude/docs/mcp
  3. Anthropic Tool Use Guide: https://docs.anthropic.com/claude/docs/tool-use
  4. Enterprise AI Assistant Patterns (Forrester, 2024)

Document Classification: Business Confidential Review Cycle: Quarterly Owner: Product Marketing Adapted for: HeliosDB-Lite Embedded Database