How the MCP Server Facilitates Interaction Between AI Assistants and Turso Databases

The Turso CLI includes a built-in Model Context Protocol (MCP) server that enables AI assistants to query and manipulate databases via JSON-RPC over stdio, eliminating the need for embedded database drivers.

The tursodatabase/turso repository ships with a built-in Model Context Protocol (MCP) server that bridges AI assistants with Turso's SQLite-compatible database engine. By exposing database operations through a standardized JSON-RPC interface, the MCP server allows AI coding assistants to inspect schemas, execute queries, and modify data without requiring native database drivers or complex integration code.

Launching the MCP Server Mode

The MCP server activates through the --mcp flag defined in cli/app.rs. When present, the CLI bypasses the interactive REPL and launches the server as a persistent process that reads JSON-RPC messages from stdin and writes responses to stdout.

Start the server with a specific database file:

tursodb my_database.db --mcp

If the database file does not exist, the server creates it automatically upon receiving the open_database tool call.

JSON-RPC Request Dispatch in cli/mcp_server.rs

The core implementation resides in cli/mcp_server.rs, where the TursoMcpServer struct processes incoming JsonRpcRequest objects. The handle_request method routes each request to one of three specialized handlers based on the method field.

Initialize Handler

The handle_initialize function returns the server's protocol version and capabilities, establishing the MCP session and confirming JSON-RPC 2.0 compatibility.

Tools List Handler

The handle_list_tools function enumerates nine available tools including open_database, list_tables, execute_query, insert_data, and schema_change. This discovery mechanism allows AI assistants to understand available capabilities without hardcoding endpoint logic.

Tool Call Handler

The handle_call_tool method maps incoming tool invocations to concrete Rust functions that interact with the underlying turso_core engine. Each tool name in the JSON-RPC request corresponds to a specific database operation implemented as a thin wrapper around SQL execution.

Database Tool Implementation Details

Each tool is a thin wrapper around Turso's database engine. For example, list_tables executes SELECT name FROM sqlite_schema WHERE type='table' against the current connection and returns a comma-separated list of table names. Other tools perform specific operations:

  • execute_query: Runs read-only SELECT statements and returns formatted result tables
  • insert_data: Handles DML operations with basic parameter validation
  • schema_change: Executes DDL statements like CREATE TABLE or ALTER TABLE
  • open_database: Initializes connections to SQLite files or in-memory databases

Connection State Management

The server maintains shared state through thread-safe wrappers to handle concurrent access. The active database connection is stored as Arc<Mutex<Arc<Connection>>>, while the current database path uses Arc<Mutex<Option<String>>>. When a client invokes open_database, the server creates necessary directories, opens the SQLite file (or establishes an in-memory connection), and updates these protected structures before confirming success.

Protocol Compliance and Graceful Shutdown

The implementation follows JSON-RPC 2.0 specifications strictly to ensure interoperability with any MCP-compatible client:

  • Notifications: Requests without an id field generate no responses
  • Method errors: Unknown methods return error code -32601 (Method not found)
  • Parameter errors: Malformed arguments return error code -32602 (Invalid params)

For interrupt handling, the server uses an AtomicUsize counter to track signals like Ctrl-C. The main loop polls this counter every 100 milliseconds, triggering graceful shutdown when an interrupt is detected.

Integrating with AI Assistants

AI assistants such as Claude or Cursor integrate by launching tursodb <db>.db --mcp as a subprocess and communicating over stdin/stdout. This stateless, language-agnostic pattern allows any MCP-compatible client to discover capabilities dynamically and generate calls without embedding database-specific code.

Example: Listing Available Tools

Send a JSON-RPC request to enumerate capabilities:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list"
}

The server responds with tool metadata:

{
  "jsonrpc":"2.0",
  "id":1,
  "result":{
    "tools":[
      {"name":"open_database","description":"Open or create a database file"},
      {"name":"list_tables","description":"List all tables in the database"},
      {"name":"execute_query","description":"Execute a read‑only SELECT query"}
    ]
  }
}

Example: Python Client Implementation

Any language can communicate with the server via subprocess management:

import json, subprocess, sys

proc = subprocess.Popen(
    ["tursodb", "my.db", "--mcp"],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    text=True
)

def send(req):
    proc.stdin.write(json.dumps(req) + "\n")
    proc.stdin.flush()
    return json.loads(proc.stdout.readline())

# Initialise the server

send({"jsonrpc":"2.0","id":0,"method":"initialize","params":{}})

# List tables

resp = send({"jsonrpc":"2.0","id":1,"method":"tools/call",
             "params":{"name":"list_tables"}})
print(resp["result"]["content"][0]["text"])

Example: Executing a Query

To run SQL through the MCP interface:

{
  "jsonrpc":"2.0",
  "id":2,
  "method":"tools/call",
  "params":{
    "name":"execute_query",
    "arguments":{"query":"SELECT name FROM sqlite_schema WHERE type='table'"}
  }
}

The server returns a formatted text table that the client can parse or display directly.

Summary

  • The --mcp flag in cli/app.rs switches the CLI from REPL mode to JSON-RPC server mode, enabling stdio-based communication
  • Request handling in cli/mcp_server.rs routes messages through handle_request to specialized handlers for initialization, tool listing, and tool execution
  • Nine database tools expose Turso core functionality including schema inspection, read-only queries, data insertion, and DDL operations
  • Thread-safe state management uses Arc<Mutex<Arc<Connection>>> and Arc<Mutex<Option<String>>> to protect the active database connection and file path
  • Full JSON-RPC 2.0 compliance with standard error codes (-32601, -32602) ensures predictable behavior across MCP clients
  • AI assistants integrate via subprocess communication, making database interaction driver-free and language-agnostic

Frequently Asked Questions

What MCP protocol version does the Turso server implement?

The server implements the Model Context Protocol through JSON-RPC 2.0 semantics. The handle_initialize function in cli/mcp_server.rs returns the server's protocol version and capability set, establishing the session contract with connecting AI assistants.

How does the server handle concurrent database connections?

The server maintains a single active connection wrapped in Arc<Mutex<Arc<Connection>>>, serializing access through mutex locking. Clients must explicitly invoke the open_database tool before executing queries, and only one database connection remains active per server process.

Can the MCP server run in-memory databases?

Yes. When open_database is invoked, the server can create in-memory SQLite databases or initialize new file-based databases by creating directories as needed. The shared connection state updates to reflect the new database path through Arc<Mutex<Option<String>>>.

What error codes does the MCP server return for invalid requests?

The server returns standard JSON-RPC 2.0 error codes: -32601 for unknown methods and -32602 for invalid parameters. These codes allow MCP clients to implement predictable error handling without parsing custom error messages.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →