A MongoDB read-only user for an AI agent, and the MCP server's read-only mode

MongoDB's readWrite role can drop collections. Here is a user an agent can't write with, a role that can write but not drop, and the MCP server flag that hides write tools.

The short answer

Create a dedicated user with the built-in read role on the one database the agent needs, and give the agent that user’s connection string, nowhere else to connect. If you run the MongoDB MCP server, add --readOnly too, which removes its create, update and delete tools. If the agent must write, use a custom role with insert and update but without remove, dropCollection or dropIndex, because the built-in readWrite role includes all three.

Deedglass reads what Postgres actually committed, not what the agent reported. In our demo a hidden trigger turned 1 row into 301; a person countersigned the undo and all 301 rows came back.

What the built-in roles allow

MongoDB’s role descriptions, with the actions that matter for an agent:1

Role Reads Inserts and updates Deletes documents Drops collections Drops the database
read yes no no no no
readWrite yes yes yes (remove) yes (dropCollection) no
readAnyDatabase yes, every database except local and config no no no no
dbAdmin partial no no yes yes (dropDatabase)
dbOwner yes yes yes yes yes

The trap is readWrite. It sounds like “can change documents”, but its actions include dropCollection and dropIndex.1 An agent told to “clean up the test data” with a readWrite user can drop a whole collection.

A read-only user

Run this in mongosh as an administrator. passwordPrompt() asks for the password instead of putting it in your shell history.3

Code Program code, for developers. The text around it says what it does.

use admin
db.createUser({
  user: "agent_ro",
  pwd: passwordPrompt(),
  roles: [ { role: "read", db: "app" } ]
})

The role applies to the app database only. The agent can run find, list collections and indexes, and open change streams,1 and nothing else.

Connection string for the agent:

Code What the screen or file shows, copied as is.

mongodb://agent_ro:<password>@db.internal:27017/app?authSource=admin

Put it in the environment the agent reads, not in a committed config file.

A role that writes but can’t drop

Sometimes an agent needs to insert or update documents: logging results, updating a status field. A custom role grants exactly the actions you list, on the resource you name.2

Code Program code, for developers. The text around it says what it does.

use admin
db.createRole({
  role: "agentWriteNoDelete",
  privileges: [
    {
      resource: { db: "app", collection: "tasks" },
      actions: [ "find", "insert", "update" ]
    },
    {
      resource: { db: "app", collection: "" },
      actions: [ "find", "listCollections", "listIndexes" ]
    }
  ],
  roles: []
})

db.createUser({
  user: "agent_rw",
  pwd: passwordPrompt(),
  roles: [ { role: "agentWriteNoDelete", db: "admin" } ]
})

The agent can read every collection in app, and insert and update only in tasks. No remove, no dropCollection, no dropIndex, no createIndex. If it tries db.tasks.deleteMany({}) or db.tasks.drop(), the server refuses.

An update can still overwrite fields with wrong values. For a field that matters, keep a history: write changes to a separate collection, or use change streams to record them, so you can see and undo what the agent did.

The MongoDB MCP server’s read-only mode

MongoDB’s own MCP server has three controls, all documented in its README:4

Option What it does
--readOnly / MDB_MCP_READ_ONLY=true allows only read, connect and metadata operations; create, update and delete tools aren’t registered
--disabledTools removes tools by name, operation type or category
confirmationRequiredTools asks before named tools; by default drop-database, drop-collection, delete-many, drop-index and some Atlas tools

--readOnly defaults to false, but the README’s examples include it, with a note to remove it only if you need writes.4 A config that combines the flag with a read-only user:

Code Data in JSON, the format software uses to pass records and settings.

{
  "mcpServers": {
    "mongodb": {
      "command": "npx",
      "args": ["-y", "mongodb-mcp-server@latest", "--readOnly"],
      "env": { "MDB_MCP_CONNECTION_STRING": "${MONGODB_AGENT_URI}" }
    }
  }
}

Use both. The flag hides tools from the model; the database user decides what any connection can do. And note one requirement on confirmations: they need a client that supports elicitation.4 On a client that doesn’t, check what happens before you rely on the prompt.

The shell is a gap

Coding agents don’t only use MCP. They also run mongosh from the terminal. We ran Deedglass’s shell guard from 0.13.0 against mongosh --eval "db.dropDatabase()" and it had nothing to ask: its catalog covered SQL and ORM commands, not MongoDB.5 0.14.1 added a row: mongosh or mongo with --eval code that calls dropDatabase() or a collection’s drop() now gets an ask, while reads such as db.stats() pass.5 The guard also reads text only, so a value known at run time passes untouched.5 For MongoDB, the user’s role is the control that holds. If the agent’s connection string belongs to agent_ro, dropDatabase fails at the server whatever tool sent it.

A checklist

  • The agent has its own user, not the application’s or an admin’s.
  • That user has read on one database, or a custom role naming its collections.
  • No readWrite, dbAdmin or dbOwner for agents.
  • The connection string lives in an environment variable.
  • The MCP server runs with --readOnly unless writes are needed.
  • Destructive tools are in confirmationRequiredTools, and your client supports the prompt.

Questions people ask

Can a MongoDB readWrite user drop a collection?

Yes. The readWrite role’s actions include dropCollection and dropIndex, as well as remove.1

How do I make the MongoDB MCP server read-only?

Start it with --readOnly or set MDB_MCP_READ_ONLY=true. Create, update and delete tools are then not registered.4

Which MongoDB role can only read?

read, on the database you name. readAnyDatabase reads every database except local and config.1

Can the MongoDB MCP server ask before dropping a collection?

Yes, by default: confirmationRequiredTools includes drop-database, drop-collection, delete-many and drop-index, but the prompt needs a client that supports elicitation.4

The same idea for other databases: a MySQL read-only user, safe Postgres access for agents, and the glossary entry on read-only database access. For SQL and ORM commands an agent might run, see migration commands that delete data, and for the config file itself, the ten-minute MCP config audit.

To see what your agent setup can change, run npx deedglass scan in the repository (what the grade means), or watch the checks in the playground.

Written with AI assistance and checked against our claims register.

The takeaway

readWrite includes dropCollection, so give agents read or a custom role without remove and drop; our guard asks on mongosh dropDatabase since 0.14.1.

Read nextA MySQL read-only user for an AI agent: grants, limits and the gaps Try it: install in 7 s

Related on this site

More posts

Sources

  1. 1MongoDB manual: Built-in roles · mongodb.com · checked 27 October 2026
  2. 2MongoDB manual: db.createRole() · mongodb.com · checked 27 October 2026
  3. 3MongoDB manual: db.createUser() · mongodb.com · checked 27 October 2026
  4. 4mongodb-js/mongodb-mcp-server README · github.com · checked 27 October 2026
  5. 5Deedglass docs: The shell guard · docs.deedglass.com · checked 27 October 2026

Published 27 October 2026, updated 28 October 2026, sources last checked 28 October 2026. If something here is out of date, write to hello@deedglass.com.

Try it on your own setup

npx deedglass scan

Grades only your own setup. Nothing is uploaded.

Pricing