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

> Discover how the Turso MCP server uses JSON-RPC over stdio to connect AI assistants with Turso databases, simplifying interaction without database drivers.

- Repository: [Turso Database/turso](https://github.com/tursodatabase/turso)
- Tags: architecture
- Published: 2026-06-23

---

**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`](https://github.com/tursodatabase/turso/blob/main/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:

```bash
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`](https://github.com/tursodatabase/turso/blob/main/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:

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

```

The server responds with tool metadata:

```json
{
  "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:

```python
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:

```json
{
  "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`](https://github.com/tursodatabase/turso/blob/main/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`](https://github.com/tursodatabase/turso/blob/main/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`](https://github.com/tursodatabase/turso/blob/main/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.