Skip to main content

Overview

This example demonstrates integrating a Couchbase database with an AI agent using the Model Context Protocol (MCP). The agent can understand natural language queries, interact with Couchbase to retrieve or manipulate data, and provide meaningful responses about hotels, airports, airlines, routes, and landmarks.

Features

  • Natural Language Queries - Ask questions in plain English
  • SQL++ Generation - Automatically generate Couchbase queries
  • Travel Sample Database - Pre-configured with travel data
  • MCP Integration - Standard protocol for database access
  • Jupyter Notebook - Interactive development environment
  • Comprehensive Schema - Hotels, airports, airlines, routes, landmarks

Introduction to Model Context Protocol (MCP)

The Model Context Protocol (MCP) is an open standard designed to standardize how AI assistants and applications connect to and interact with external data sources, tools, and systems.

Key Goals and Features

  • Standardized Communication - Common language for AI-to-backend communication
  • Enhanced Context Management - Efficient handling of LLM context windows
  • Secure Data Access - Controlled infrastructure exposure
  • Tool Use and Actionability - Retrieve information and trigger actions
  • Interoperability - Ecosystem where AI tools work together
  • Client-Server Architecture:
    • MCP Hosts/Clients: Applications that access data
    • MCP Servers: Programs exposing data sources through MCP

Architecture

Prerequisites

  • Python 3.8+
  • Jupyter Notebook or JupyterLab
  • Couchbase Server with travel-sample database
  • Nebius API key
  • mcp-server-couchbase installed

Installation

1

Setup Couchbase

Install Couchbase Server and load the travel-sample dataset:
# Follow Couchbase installation guide
# Load travel-sample from Couchbase Console
2

Clone MCP Server

git clone https://github.com/Couchbase-Ecosystem/mcp-server-couchbase
cd mcp-server-couchbase
3

Configure Environment

Create .env file:
COUCHBASE_HOST=your_couchbase_host
COUCHBASE_BUCKET_NAME=travel-sample
COUCHBASE_USERNAME=your_username
COUCHBASE_PASSWORD=your_password
NEBIUS_API_KEY=your_nebius_api_key
4

Install Dependencies

pip install agents openai python-dotenv

Database Structure

Couchbase organizes data hierarchically:
1

Cluster

Overall container of all Couchbase data and services
2

Bucket

Similar to a database in traditional systemsExample: travel-sample
3

Scope

Namespace within a bucket that groups collectionsExample: inventory
4

Collection

Equivalent of a table in relational databasesCollections: airport, airline, route, landmark, hotel
5

Document

Atomic data unit (JSON) stored in a collectionEach document has a unique key

Implementation

Notebook Setup

Create main.ipynb:
import asyncio
import os
import shutil

from agents import Agent, Runner, gen_trace_id, trace, OpenAIChatCompletionsModel
from agents.mcp import MCPServer, MCPServerStdio
from openai import AsyncOpenAI
from dotenv import load_dotenv

load_dotenv()

Configure OpenAI Client

api_key = os.environ["NEBIUS_API_KEY"]
base_url = "https://api.tokenfactory.nebius.com/v1"
client = AsyncOpenAI(base_url=base_url, api_key=api_key)

Define Query Function

async def qna(agent):
    # Query 1: Database info
    message = "Tell me about the database that you are connected to."
    print(f"Running: {message}")
    result = await Runner.run(starting_agent=agent, input=message)
    print(result.final_output)

    # Query 2: Top hotels
    message = "List out the top 5 hotels by the highest aggregate rating?"
    print(f"\n\nRunning: {message}")
    result = await Runner.run(starting_agent=agent, input=message)
    print(result.final_output)

    # Query 3: Travel recommendation
    message = "Recommend me a flight and hotel from New York to San Francisco"
    print(f"\n\nRunning: {message}")
    result = await Runner.run(starting_agent=agent, input=message)
    print(result.final_output)

    # Query 4: UK sightseeing
    message = """I'm going to the UK for 1 week. Recommend some great spots 
    to visit for sightseeing. Also mention the respective prices of those 
    places for adults and kids."""
    print(f"\n\nRunning: {message}")
    result = await Runner.run(starting_agent=agent, input=message)
    print(result.final_output)

    # Query 5: Budget hotel
    message = "My budget is around 30 pounds a night. What will be the best hotel to stay in?"
    print(f"\n\nRunning: {message}")
    result = await Runner.run(starting_agent=agent, input=message)
    print(result.final_output)

Create Agent with MCP

async def run(mcp_server: MCPServer):
    agent = Agent(
        name="Assistant",
        instructions="""Couchbase organizes data with the following hierarchy:

        1. Cluster - Overall container of all data and services
        2. Bucket - Similar to a database (e.g., "travel-sample")
        3. Scope - Namespace within bucket (use "inventory" scope)
        4. Collection - Equivalent of a table (airport, airline, route, landmark, hotel)
        5. Document - JSON document with unique key

        Use the tools to read the database and answer questions.
        The data is inside `inventory` scope, so use only that scope.
        Any query you generate needs to have only the collection name in the FROM clause.
        Every field, collection, scope or bucket name inside the query should be 
        inside backticks (``).
        """,
        model=OpenAIChatCompletionsModel(
            model="meta-llama/Meta-Llama-3.1-8B-Instruct",
            openai_client=client
        ),
        mcp_servers=[mcp_server],
    )

    await qna(agent=agent)

Main Execution

async def main():
    # Configure MCP server
    async with MCPServerStdio(
        params={
            "command": "/path/to/uv",
            "args": [
                "--directory",
                "/path/to/mcp-server-couchbase",
                "run",
                "--env-file",
                ".env",
                "mcp_server.py"
            ]
        }
    ) as mcp_server:
        await run(mcp_server)

# Run the notebook
await main()

MCP Integration Details

MCPServerStdio Configuration

from agents.mcp import MCPServerStdio

async with MCPServerStdio(
    params={
        "command": "uv",  # Python environment manager
        "args": [
            "--directory",
            "/path/to/mcp-server-couchbase",  # Server location
            "run",
            "--env-file",
            ".env",  # Couchbase credentials
            "mcp_server.py"
        ]
    }
) as mcp_server:
    # Use mcp_server with agent

Available MCP Tools

The mcp-server-couchbase provides:
Execute SQL++ (N1QL) queries against Couchbase.Example:
SELECT * FROM `hotel` 
WHERE `ratings`.`Overall` = 5.0 
LIMIT 5
List all scopes and collections in the bucket.Returns:
{
  "scopes": [
    {
      "name": "inventory",
      "collections": ["airport", "airline", "route", "landmark", "hotel"]
    }
  ]
}
Retrieve a specific document by key.Parameters:
  • collection: Collection name
  • document_id: Document key
Returns: JSON document
Insert a new document.Parameters:
  • collection: Collection name
  • document: JSON document
Update an existing document.
Delete a document by key.

Query Examples

Query:
Tell me about the database that you are connected to.
Agent Response:
I am connected to a database with the following structure:

- Main scope: inventory
- Collections:
  1. airport
  2. airline
  3. route
  4. landmark
  5. hotel

Each collection stores data as JSON documents related to 
airports, airlines, travel routes, landmarks, and hotels.

SQL++ Query Generation

The agent generates Couchbase SQL++ queries following these rules:

Query Format

-- Correct: Only collection name in FROM
SELECT * FROM `hotel` WHERE `ratings`.`Overall` = 5.0

-- Incorrect: Including scope/bucket
SELECT * FROM `inventory`.`hotel`  -- Don't do this

Backtick Usage

-- All identifiers must use backticks
SELECT `name`, `city`, `ratings`.`Overall` 
FROM `hotel`
WHERE `country` = 'United States'

Common Patterns

-- Top N results
SELECT `name`, `ratings`.`Overall` AS rating
FROM `hotel`
ORDER BY `ratings`.`Overall` DESC
LIMIT 5

-- Filtered results
SELECT `name`, `address`, `price`
FROM `hotel`
WHERE `country` = 'United Kingdom' 
  AND `price` <= 30

-- Join collections
SELECT h.`name`, a.`name` AS airport
FROM `hotel` h
JOIN `airport` a ON h.`city` = a.`city`
WHERE h.`country` = 'United States'

Workflow

Best Practices

Agent Instructions

  • Provide clear database structure
  • Specify scope to use
  • Define query formatting rules
  • Include backtick requirements

Query Design

  • Use only collection names in FROM
  • Enclose all identifiers in backticks
  • Specify scope in instructions
  • Use appropriate LIMIT clauses

Error Handling

  • Handle connection errors gracefully
  • Validate query syntax
  • Provide clear error messages
  • Log MCP tool errors

Performance

  • Use indexes for common queries
  • Limit result set sizes
  • Cache schema information
  • Monitor query execution time

Troubleshooting

Check Couchbase credentials in .env:
COUCHBASE_HOST=localhost
COUCHBASE_BUCKET_NAME=travel-sample
COUCHBASE_USERNAME=Administrator
COUCHBASE_PASSWORD=password
Verify paths and permissions:
params={
    "command": "/full/path/to/uv",
    "args": [
        "--directory",
        "/full/path/to/mcp-server-couchbase",
        "run",
        "mcp_server.py"
    ]
}
Common issues:
  • Missing backticks around identifiers
  • Including scope in FROM clause
  • Wrong field paths in nested JSON
Review agent instructions for query rules.
  • Verify travel-sample is loaded
  • Check scope/collection names
  • Review query filters
  • Test query in Couchbase Console

Advanced Features

Custom Collections

Add your own collections:
instructions = """
... (existing instructions) ...

Additional collections:
- `custom_collection`: Your custom data
- Use same query rules for custom collections
"""

Multi-Scope Support

Extend to multiple scopes:
instructions = """
Available scopes:
- inventory: Hotels, airlines, routes
- tenant_agent_00: User bookings

Always specify which scope to query.
"""

Aggregation Queries

SELECT `country`, COUNT(*) AS hotel_count,
       AVG(`ratings`.`Overall`) AS avg_rating
FROM `hotel`
GROUP BY `country`
ORDER BY avg_rating DESC

Source Code

View the complete implementation at: ~/workspace/source/mcp_ai_agents/couchbase_mcp_server/

Couchbase

Couchbase database platform

MCP Server Couchbase

Official MCP server

Database MCP Agent

GibsonAI database management

Custom MCP Server

Build custom MCP servers

Build docs developers (and LLMs) love