---
sidebar_position: 6
title: query
description: Execute SQL queries against MotherDuck databases
---

# query

Execute **read-only** SQL queries against MotherDuck databases.

## Description

The `query` tool executes SQL queries against your MotherDuck databases. For cross-database queries, use fully qualified names: `database.schema.table` (or `database.table` for the main schema).

`query` is for read-only SQL. Operations that modify data, schema, or account settings, or trigger side effects, are rejected. For SQL that can change data or schema, use [`query_rw`](/sql-reference/mcp/query-rw/).

## Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `database` | string | Yes | Database name to query |
| `sql` | string | Yes | DuckDB SQL query to execute |

## Output Schema

```json
{
  "success": boolean,
  "columns": string[],           // Column names (on success)
  "columnTypes": string[],       // Column types (on success)
  "rows": any[][],               // Query results (on success)
  "rowCount": number,            // Number of rows returned (on success)
  "error": string,               // Error message (on failure)
  "errorType": string            // Error type (on failure)
}
```

## Limits

- **Result limit:** Maximum 2,048 rows and 50,000 characters. Results exceeding these limits will be truncated with a truncation message.
- **Query timeout:** 55 seconds, to stay within common client timeouts. Queries exceeding this limit will be cancelled server-side and the tool will respond with an error message.

## Example Usage

**Simple query:**

```text
Query the top 5 customers by total orders from my_database
```

The AI assistant will call the tool with:

```json
{
  "database": "my_database",
  "sql": "SELECT customer_name, COUNT(*) as order_count FROM orders GROUP BY customer_name ORDER BY order_count DESC LIMIT 5"
}
```

**Cross-database query:**

```text
Join the users table from auth_db with orders from sales_db
```

```json
{
  "database": "auth_db",
  "sql": "SELECT u.name, o.order_id, o.amount FROM auth_db.main.users u JOIN sales_db.main.orders o ON u.id = o.user_id LIMIT 100"
}
```

## Success Response Example

```json
{
  "success": true,
  "columns": ["customer_name", "order_count"],
  "columnTypes": ["VARCHAR", "BIGINT"],
  "rows": [
    ["Acme Corp", 150],
    ["TechStart Inc", 89],
    ["Global Services", 72]
  ],
  "rowCount": 3
}
```

## Error Response Example

```json
{
  "success": false,
  "error": "Query is not read-only",
  "errorType": "ForbiddenQueryError"
}
```
