Would you notice? AI assistants, MCP servers and your databases
If an AI assistant is connected to one of your production databases this week, would you notice? And if something went wrong, could you tell anyone what it did? I ask a lot of data professionals this question, and the honest answer is usually some version of “probably not.” That's not a criticism, but most of us built our monitoring, auditing and access models for people and applications. AI assistants and MCP servers don't fit into those buckets, and they've arrived faster than most of our processes have changed, so we consider it someone else’s problem.
When we compare it to the findings in the Redgate's State of the Database Landscape 2026 report, AI use in database management jumped from 15% to 44% in a single year. Only 23% of organizations have a formal data governance or quality framework. Of those, only 58% say they accept higher risk as a trade-off for efficiency, which makes sense- DBAs are risk-averse by nature. At the same time, people know they're taking on risk, and they're doing it anyway, because the productivity gain is what AI is sold on.
For most of us, the question isn't whether to allow AI near our databases as it’s already there in one form or another. A developer wired an MCP server into their IDE to chase a bug, or an analyst is asking a chat assistant questions in plain English and letting it write the SQL. We’ve got someone's building an agent that runs on a schedule with nobody watching each step and often, none of these needed a change request, and most of them used a connection string and login someone already had.
The real question becomes whether you'd notice if something went wrong and it was the question we asked recently when John Martin and I did a talk at PASS Summit West 2026 and how you would.
Assistants in Databases
Before we can govern this, it helps to be clear about the path, as there are four hops between a person and your data, and each one adds its own risk.
- A person asks a question, often a vague one. “Just fix it” is a perfectly valid prompt as far as the assistant is concerned.
- The AI assistant plans the steps. The model decides which tools to call and in what order. It can also be steered by text it reads along the way.
- An MCP server exposes the tools. The Model Context Protocol is the open standard that lets an assistant call tool on a server. For databases, that usually means things like run_query and list_tables, and sometimes an execute tool that runs whatever SQL the model writes.
- The database sees one login. Whatever rights that login has, the model effectively has been given.
The last hop is the one that matters most to us, as the database only sees the last step in the chain. It has no idea whether a person typed that query or a model generated it, unless it was clearly identified as part of the request.
From there, we group the risks into six areas:
- Over-privileged credentials. The MCP server connects as somebody, usually whoever sets it up. If that's a developer with db_owner, the model has db_owner.
- Shared identity. If the assistant uses a shared service account or someone's personal login, its activity is invisible in every log you have.
- Prompt injection through data. The model reads results. If a row, a support ticket or a document contains instructions, the model may follow them on its next tool call.
- Unbounded workload. Assistants query at machine speed and love to explore: schema crawls, SELECT *, full scans on the primary at ten in the morning.
- Data leaving the boundary. Result sets go to a model provider and live on in chat history, IDE logs and shared transcripts.
- Write and DDL tools. Combine an execute tool, auto-approve and a vague prompt, and you're one “fix it” away from an UPDATE without a WHERE clause.
The first two deserve the most attention, because they make the other four invisible.
To Each Their Own Identity
If you take one thing from this post, make it this: every person, every assistant, every MCP server and every agent gets its own identity.
I think it’s obvious why, but just in case, let’s dig in. Picture three different actors, a developer, their IDE assistant and an analyst's chat assistant, all connected through one service account. Your log says svc_app SELECT * FROM dbo.Customers. It's accurate, and it's useless for many database platforms to identify who performed what.
Now give each one its own login and this becomes simpler on many levels. The developer uses their own account for their own work. The IDE assistant's MCP server gets mcp_dev_ro, read-only and scoped to staging. The analyst's assistant gets mcp_reporting_ro, pointed at a readable secondary. A triage agent gets agent_triage_ro, and it expires in 30 days. Suddenly every one of them shows up separately in sessions, monitoring, audit and permission reviews. If you’re working through an audit, you would be able to force least privilege for each entity and not concern yourself with impacting the functionality of another.
Taking this a step further, we’ll focus on five properties for every one of these identities:
- least privilege
- scoped
- expiring
- revocable
- visible.
For a SQL Server MCP server, this might look like the following:
-- One login per MCP server: read-only, scoped
CREATE LOGIN mcp_reporting_ro
WITH PASSWORD = N'<from your vault>', CHECK_POLICY = ON;
USE SalesReporting;
CREATE USER mcp_reporting_ro FOR LOGIN mcp_reporting_ro;
GRANT SELECT ON SCHEMA::reporting TO mcp_reporting_ro;
DENY SELECT ON SCHEMA::pii TO mcp_reporting_ro;
-- Tag the connection so it is visible everywhere:
-- Server=sql-rpt;Database=SalesReporting;
-- ApplicationIntent=ReadOnly;
-- Application Name=mcp-reporting-ro;
A few noteworthy call outs:
- The password comes from a vault, not a config file. Better still, if you can use Entra ID or a managed identity, there's no secret to leak at all.
- Grant by schema and add an explicit DENY on anything sensitive. Someday someone will add this user to a role to fix a permissions error. The DENY still wins.
- Set Application Name on the connection. It costs nothing and makes the session distinguishable in sys.dm_exec_sessions, in your monitoring tool and in audit. ApplicationIntent=ReadOnly routes it to a readable secondary when you have an availability group listener, which keeps exploratory queries off your primary.
The same thinking applies to the MCP server itself. Before you let one near your estate, ask six questions:
- Can it change anything?
- Whose identity does it use?
- What can it reach?
- When does access end?
- Is it rate limited?
- Is it logged?
As an example of good answers, Redgate Monitor's MCP server exposes read-only tools that can't change Monitor or your databases. It uses a dedicated token with an MCP role, rejects other token types, is scoped to the servers you choose, has an expiry, is rate limited to 60 calls a minute by default, logs every request and is HTTPS only. Whatever tool you're evaluating, those questions should have answers. If the answer to “can it change anything?” is “yes, it has an execute tool,” at least you now know what you're approving.
Five Reasonable Decisions in One Week
Access rarely grows because someone makes a bad decision, but because people make a series of reasonable ones in separated succession. Here's a week I've seen play out in some form more than once.
Monday: chase a bug in staging. A developer adds an SQL Server MCP server to their IDE assistant and uses their own login, because it's already in their connection manager. What resulted was that the assistant now has everything the developer has, db_owner on staging, and staging is a restore of production with real customer data in it. Recommended practice would have the MCP server receive its own read-only login, and non-production data is masked.
Tuesday: point it at production “just to check.” The bug only reproduces in production, so one line in the connection string changes. What resulted was the same personal login, now with production rights, running exploration queries against the primary during business hours. Our recommended practice would have a separate production identity, a readable secondary, and elevated access that's time-boxed and approved, so it ends on its own.
Wednesday: share the config. An analyst sees it working and wants the same setup. The fastest path is the team repo, connection string and password included. What resulted were two people and two assistants behind one credential, and a secret that now lives in Git history forever. Our recommended practice would have had one identity per person and per assistant, secrets from a vault, and rotation the moment a secret land in a repo or a chat.
Thursday: turn on write tools. The assistant finds a data problem and offers to fix it. Someone enables the write tool and turns on auto-approve so it stops asking. Suddenly an UPDATE and DDL flowing through an identity nobody reviews, and prompt injection going from embarrassing to destructive. If recommended practices have been followed, the assistants are read-only by default, and fixes go through the same reviewed deployment pipeline as every other change.
Friday, 4:45 pm: incident. The orders data looks wrong. Someone remembers the assistant had written access yesterday, and the question lands on the DBA asking them to confirm what the AI assistant did via a log review.
Considering what was built in the previous week, there's no good answer. One shared login, no application name, no audit, and the assistant's history sitting on two laptops, it will be difficult, if not impossible to track. Nobody decided to give an AI assistant write access to production through a shared credential, and yet that's exactly where we ended up.
The rest of this post is about making that Friday question answerable, so you’re able to recognize the assistant in the first place, keeping configuration hardened, and having the evidence ready before you need it.
Spotting What You Already Monitor
The good news is that you probably already collect most of what you need to notice an assistant. You just must know what to look for. The six signals to watch for are:
- A new login or program name. program_name values like node or python, an mcp-something application name, or a login you've never seen before.
- Schema crawling. An assistant's first move is usually to discover the schema, so you'll see bursts of sys.objects, sys.columns and INFORMATION_SCHEMA queries.
- Machine-speed bursts. A person writes a query every minute or two. An assistant can issue dozens of distinct ad hoc statements a minute from a single session.
- Broad reads. SELECT *, TOP 1000 and full scans across many tables showing up in your top queries.
- Off-pattern timing. A person's login active at 2 a.m. may be an agent using their credential.
- Permission changes. New role memberships or grants, especially db_owner and sysadmin. When something hits a permissions error, the “fix” is often adding a role, and that's exactly where access grows.
You can start looking today with nothing more than the DMVs. The first query is an inventory of who's connected and what:
-- Who is connected, and as what?
SELECT login_name, program_name, host_name,
COUNT(*) AS sessions,
MAX(last_request_start_time) AS last_active
FROM sys.dm_exec_sessions
WHERE is_user_process = 1
GROUP BY login_name, program_name, host_name
ORDER BY sessions DESC;
Run it a few times a day for a week and you'll learn what's connecting. Most people find at least one surprise when monitoring this.
The second query results in a single number you can trend and alert on:
-- One number to trend and alert on
SELECT COUNT(*)
FROM sys.dm_exec_sessions
WHERE is_user_process = 1
AND (program_name LIKE N'%mcp%'
OR login_name LIKE N'mcp[_]%'
OR login_name LIKE N'agent[_]%');
This is the payoff for naming your identities consistently. In Redgate Monitor, that query becomes a custom metric you can chart and alert on which offers you a way to extend your monitoring capabilities.
Something to keep in mind: program_name is set by the client and can be anything. This is important to know and understand, it’s not malicious, as identity and audit are the controls and our goal is visibility.
In a monitoring tool, put all of this together for a window of time to include sessions, top queries and who ran them. With a dedicated login and application name, the assistant's schema crawl and broad reads stand out immediately next to a session on a shared login, where you can't tell who's behind it. If your tool tracks permissions history, as Redgate Monitor Enterprise does, you can also see when an identity's access grows, not just what it is now, and alert on the change as it happens.
Show Your Drift
Identity limits who can connect and simplify what to give extra scrutiny when monitoring. A hardened baseline limits what a connection can do once it's there and tells you when those changes.
The CIS Benchmarks for SQL Server are a consensus hardening baseline, and they map surprisingly well to the AI problem:
- Reduce attack surface. With xp_cmdshell, CLR and OLE Automation off, a steered prompt can't reach the operating system.
- Logins and authentication. With sa disabled and password policy enforced, there's no all-powerful account for anyone, or anything, to borrow.
- Role permissions. Minimal rights for public and guest mean a new login, like an MCP server's, starts with nothing.
- Auditing. Login auditing and a server audit mean there's a record when you need one.
- Network and instance exposure. Fewer endpoints and remote options mean fewer paths for a stray client.
- Encryption and backups. Data stays protected in transit and at rest.
Redgate Monitor ships CIS templates for SQL Server 2019, 2022 and 2025, each as a server-level and a database-level template. Apply both for full coverage of the benchmark's automated checks. The built-in templates are read-only, so duplicate one if you want to customize your environment.
Do always remember though: A baseline is only useful if you notice when it moves, so with that, consider the following scenario:
- Week three, someone enables, xp_cmdshell because an agent needs to write a file.
- Week five, the MCP login keeps hitting permission errors, so it's added to sysadmin “temporarily.”
- Week seven, TRUSTWORTHY gets turned on for a helper database.
Each of these changes is small. Together, they undo most of the hardening that was limiting what the assistant could do, so consider four habits to keep this in check:
- Apply the server and database templates to every instance, not just the ones you're worried about.
- Alert on permission changes, not just failures.
- Review non-compliant properties every week.
- Treat “temporary” as a ticket with an end date. If it doesn't have one, it isn't temporary.
Verifying AI Changes
Back to Friday afternoon, but this time with the evidence in place. Answering this question takes five sources, joined on identity and time:
- Identity: which login and which application. This only works if each entity has its own.
- Permissions history: what it could do at that moment, not what it can do now after someone tidied up.
- Workload history: sessions, top queries, waits and blocking for the window, from your monitoring.
- Audit: login, permission changes, and reads and writes on the objects you care about.
- Client and MCP logs: the prompts, tool calls and results, from the assistant's side.
Join those together and you can build a timeline like this one:
| Time | What happened |
| 09:02 | mcp_reporting_ro logs in from mcp-reporting-ro |
| 09:03 | 47 catalog queries in 40 seconds |
| 09:05 | SELECT on pii.Customers denied |
| 09:11 | UPDATE sales.Orders, 1,204 rows |
That's an actual answer vs. more questions. The prompt that led to it comes from the client logs, so make sure those live somewhere other than someone’s laptop.
If you don't have auditing on your AI identities yet, there's a starting point. Consider one server audit filtered to the AI login, so volume stays manageable even with SELECT auditing turned on:
CREATE SERVER AUDIT AI_Access
TO FILE (FILEPATH = N'D:\Audit\AI\', MAXSIZE = 256 MB)
WHERE server_principal_name = N'mcp_reporting_ro';
CREATE SERVER AUDIT SPECIFICATION AI_Access_Server
FOR SERVER AUDIT AI_Access
ADD (SUCCESSFUL_LOGIN_GROUP), ADD (FAILED_LOGIN_GROUP),
ADD (SERVER_ROLE_MEMBER_CHANGE_GROUP)
WITH (STATE = ON);
USE SalesReporting;
CREATE DATABASE AUDIT SPECIFICATION AI_Access_Db
FOR SERVER AUDIT AI_Access
ADD (SELECT, INSERT, UPDATE, DELETE, EXECUTE
ON DATABASE::SalesReporting BY public),
ADD (DATABASE_ROLE_MEMBER_CHANGE_GROUP)
WITH (STATE = ON);
ALTER SERVER AUDIT AI_Access WITH (STATE = ON);
Something to keep in mind about how this works:
- At the server level, it captures successful and failed logins and server role membership changes, which is what catches the “temporary” sysadmin.
- At the database level, it audits SELECT, INSERT, UPDATE, DELETE and EXECUTE by public, which means everyone. The server audit's predicate narrows that down to just the AI login. Denied statements are recorded with succeeded = 0, which is how the PII denial in the timeline above would show up.
- Read it back with sys.fn_get_audit_file or ship the files to your SIEM. On Linux, use a Linux path. For several AI identities, use one audit per identity or an OR in the predicate.
Notice that this only works because the login is dedicated, where with a shared login, you'd be auditing everyone. Notice how identity keeps coming back as the thing that makes every other control work.
Monday’s Task
None of what you see here requires a big program or a new tool, so here's what I'd start with, in roughly this order:
- Inventory what connects. Run the session query above for a week.
- Give every entity its own identity. Scoped, expiring, and tagged with an Application Name.
- Make read-only the default. Use readable secondaries for production which questions and send writes through review.
- Keep secrets out of config files. Use a vault or a managed identity and rotate on exposure.
- Baseline, and watch for drift. Start with the CIS Benchmark and alert on permission changes.
- Make “what did it do?” answerable. Keep audit and workload history for as long as an investigation might take to start.
Identity comes first, because the other five do depend on it.
AI is going to keep showing up in database work, and honestly, it should. It's genuinely useful. But capability isn't the same as judgment. AI brings the first; people still own the second. Our job as DBAs is to make sure that when an assistant shows up in our estate, we notice, we've limited what it can do, and we can answer for what it did.
References
This document contains proprietary information and is protected by copyright law.
Copyright © 2026 Red Gate Software Limited. All rights reserved
Read next
Blog post
Build vs Buy in the Age of AI
Every DBA has a toolbox they trust that often includes a folder of scripts refined over a decade, mostly a handful of DMV queries. These queries answer “what’s slow right now” faster than any dashboard, and a working knowledge of the environment that took years to build. So, when a new AI tool promises to answer the same questions in plain English, the first reaction is usually suspicion rather than excitement. That suspicion should be expected, but it also means a lot of DBAs are making an unspoken decision without really weighing in and kicking the tires. There’s a comfort to
Tools in this post
Redgate Monitor
Real-time multi-platform performance monitoring, with alerts and diagnostics






Loading comments...