# Restricting to read-only access


> Restrict the remote MCP server to read-only queries using client-side blocking, read scaling tokens, or proxy filtering

The remote MCP server exposes both the read-only `query` tool and the read-write `query_rw` tool. If you want to ensure your AI assistant can only read data, there are three approaches depending on your setup.

| Approach | Enforcement | Setup | Works with OAuth connectors |
|----------|------------|-------|-----------------------------|
| [Block the tool at the client](#block-the-query_rw-tool-at-the-client) | Client-side | Low (UI toggle) | Yes |
| [Use a read scaling token](#use-a-read-scaling-token) | Server-side | Medium (manual config) | No (replaces OAuth) |
| [Proxy filtering](#proxy-filtering) | Application-side | Varies | N/A (custom backend) |

## Block the `query_rw` tool at the client

The simplest approach: keep using the OAuth connector, but configure your MCP client to never call the `query_rw` tool. The server still exposes the tool, but the client will never invoke it.

Most clients support this at the **individual user** level. ChatGPT also lets **organization admins** enforce tool restrictions across all workspace members.

### Claude

Each user can block tools individually. Go to **Settings → Connectors → MotherDuck**, expand **Write/delete tools**, and select the blocked icon next to `query_rw`:

![Blocking the query_rw tool in Claude's connector settings](./img/query-rw-blocked.png)

:::note
Claude does not support org-level per-tool blocking. Team/Enterprise admins can remove a connector entirely from **Organization settings → Connectors**, but cannot selectively disable individual tools like `query_rw` for all members.
:::

> [Claude connector permissions documentation](https://support.claude.com/en/articles/11175166-get-started-with-custom-connectors-using-remote-mcp)

### ChatGPT

**Enterprise/Edu admins:** Admins can [enable or disable specific app actions after publishing](https://help.openai.com/en/articles/12584461-developer-mode-and-full-mcp-connectors-in-chatgpt-beta). Go to **Workspace Settings → Apps**, click the `...` menu next to MotherDuck, select **Action control**, and deselect `query_rw`. New tools added by the MCP server are disabled by default — admins must explicitly enable them.

**Business plans:** Per-tool Action control is not available for custom MCP apps after publishing. To change which tools are exposed, remove and recreate the app ([developer mode documentation](https://help.openai.com/en/articles/12584461-developer-mode-and-full-mcp-connectors-in-chatgpt-beta)).

### Cursor

Open **Cursor Settings** → **Tools & MCP**, expand the MotherDuck server entry, and toggle off `query_rw`.

:::note
Tool toggles are stored locally in Cursor's database, not in the `mcp.json` config file. They cannot be shared across a team through config files.
:::

### Claude Code

Add a deny rule to your `.claude/settings.json` (project-level) or `~/.claude/settings.json` (user-level):

```json
{
  "permissions": {
    "deny": ["mcp__MotherDuck__query_rw"]
  }
}
```

> [Claude Code permissions documentation](https://code.claude.com/docs/en/permissions)

### Copilot Studio

Open your agent in Copilot Studio, go to **Tools**, and open the MotherDuck MCP entry. Toggle `query_rw` off in the tool list and click **Save**. The agent only sees `query` and the schema exploration tools.

![MotherDuck MCP tool list in Copilot Studio with query_rw toggled off](/img/key-tasks/ai-and-motherduck/copilot-studio/07-tools-list.png)

## Use a read scaling token

For server-side enforcement, authenticate with a [read scaling token](/key-tasks/authenticating-and-connecting-to-motherduck/read-scaling/) instead of a regular access token. Read scaling tokens connect to dedicated read replicas that reject all write operations — even if the client calls `query_rw`, writes will fail. This requires manual configuration instead of the one-click OAuth connectors.

:::note
Read scaling connections are [eventually consistent](/key-tasks/authenticating-and-connecting-to-motherduck/read-scaling/#ensuring-data-freshness). Results may lag a few minutes behind the latest database state.
:::

You can create a read scaling token from the [MotherDuck UI](https://app.motherduck.com) under **Settings → Access Tokens** or through the [REST API](/sql-reference/rest-api/users-create-token/).

Read scaling tokens also unlock concurrent MCP sessions: each MCP instance that connects with a read scaling token is assigned to a read replica (duckling) from a pool. Up to the pool size (default 4, max 16), each connection gets its own duckling; once the pool is full, new connections are assigned to existing ducklings in round-robin. This means you can run many MCP sessions in parallel from the same account—for example, multiple AI agents or team members querying simultaneously. See [Read Scaling](/key-tasks/authenticating-and-connecting-to-motherduck/read-scaling/) for details on pool sizing and how replicas are assigned.

### Claude

Claude's web connector only supports OAuth, so you need to use the desktop config instead. Open **Settings → Developer → Edit Config** and add:

```json
{
  "mcpServers": {
    "MotherDuck": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://api.motherduck.com/mcp",
        "--header",
        "Authorization: Bearer ${MOTHERDUCK_TOKEN}"
      ],
      "env": {
        "MOTHERDUCK_TOKEN": "<your_read_scaling_token>"
      }
    }
  }
}
```

This uses [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) to bridge the remote MCP server into Claude Desktop's local stdio transport.

### ChatGPT

To use a read scaling token through your own remote connector, run an authenticated MCP wrapper that selects the token on your backend. Follow [White-label the MotherDuck MCP server](/key-tasks/ai-and-motherduck/mcp-workflows/white-label-mcp-server/) for caller authentication, service-account mapping, and tool filtering.

The wrapper must authenticate and authorize each caller before forwarding requests. An unauthenticated proxy that injects a token lets anyone who can reach its URL query the data available to that token. Read-only access prevents database writes. It doesn't protect confidential data from unauthorized reads.

Configure your client with the wrapper's URL and supported authentication flow. Keep the MotherDuck read scaling token on the backend.

### Cursor

Open **Cursor Settings** → **Tools & MCP** → **+ New MCP Server** and add the following configuration:

```json
{
  "MotherDuck": {
    "url": "https://api.motherduck.com/mcp",
    "type": "http",
    "headers": {
      "Authorization": "Bearer <your_read_scaling_token>"
    }
  }
}
```

### Claude Code

```bash
claude mcp add --transport http \
  --header "Authorization: Bearer <your_read_scaling_token>" \
  MotherDuck https://api.motherduck.com/mcp
```

### Copilot Studio

Follow the [Copilot Studio MCP setup](/key-tasks/ai-and-motherduck/mcp-setup/?mcp-client=copilot-studio) with **API key** authentication, and when prompted for the connection value, enter your read scaling token:

```text
Bearer <your_read_scaling_token>
```

The `query_rw` tool may still appear in the agent's tool list, but writes fail at the server because read scaling replicas reject write operations. For belt-and-braces, also toggle `query_rw` off in the tool list so the model never sees it as an option.

![MotherDuck MCP tool list in Copilot Studio with query_rw toggled off](/img/key-tasks/ai-and-motherduck/copilot-studio/07-tools-list.png)

### Others

For MCP-compatible clients that support simple authentication, use the following JSON configuration with a read scaling token as the Bearer value:

```json
{
  "mcpServers": {
    "MotherDuck": {
      "url": "https://api.motherduck.com/mcp",
      "type": "http",
      "headers": {
        "Authorization": "Bearer <your_read_scaling_token>"
      }
    }
  }
}
```

For clients that only support local (stdio) servers, use `mcp-remote` to bridge the connection:

```json
{
  "mcpServers": {
    "MotherDuck": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://api.motherduck.com/mcp",
        "--header",
        "Authorization: Bearer ${MOTHERDUCK_TOKEN}"
      ],
      "env": {
        "MOTHERDUCK_TOKEN": "<your_read_scaling_token>"
      }
    }
  }
}
```

## Proxy filtering

If you're integrating the remote MCP server into a backend service or custom agent framework, you can restrict access at the application layer. Expose only the tools your application needs and enforce that same set when dispatching calls. Hiding `query_rw` from the tool list is insufficient if a caller can still invoke it directly. Review Guide, Dive, Flight, sharing, and delete tools separately: a read-only SQL tool does not make every MCP operation read-only.

For tenant authentication, scoped sessions, and tool selection, see [White-label the MotherDuck MCP server](/key-tasks/ai-and-motherduck/mcp-workflows/white-label-mcp-server/).

See [Building Analytics Agents](/key-tasks/ai-and-motherduck/building-analytics-agents) for patterns on building custom agent integrations with read-only access controls.


---

## Docs feedback

MotherDuck accepts optional user-submitted feedback about this page at `GET https://motherduck.com/docs/api/feedback/agent`.
For agents and automated tools, feedback submission should be user-confirmed before sending.

URL-encode query parameter values and send a GET request:

```text
GET https://motherduck.com/docs/api/feedback/agent?page_path=%2Fkey-tasks%2Fai-and-motherduck%2Fsecuring-read-only-access%2F&page_title=Restricting%20to%20read-only%20access&text=<url-encoded user feedback, max 2000 characters>
```

Optionally append `&source=<url-encoded interface identifier>` such as `claude.ai` or `chatgpt`.

`page_path` and `text` are required; `page_title` and `source` are optional. Responses: `200 {"feedback_id": "<uuid>"}`, `400` for malformed query parameters, and `429` when rate-limited.
