Skip to main content
Glama
mssql-mcp-server

mssql-mcp-server

by Andrian17

mssql-mcp-server

A Model Context Protocol server for Microsoft SQL Server. Requires SQL Server 2017 or later (on-prem) or Azure SQL Database — several catalog queries (e.g. index/constraint/permission listings) use STRING_AGG, which does not exist before SQL Server 2017. Its tool surface — the 18 tool names, their operation values, parameters and output shapes — mirrors @henkey/postgres-mcp-server v1.0.7, the PostgreSQL MCP server many Claude/AI-client users already run, so a client that knows how to drive the Postgres server can drive this one the same way. henkey is AGPL-3.0; parity here is with the interface and behaviour, not the code — everything in this repository is written from scratch and licensed MIT (see LICENSE).

Quick start

npm install
npm run build

This produces build/index.js, a stdio MCP server. Point an MCP client at it.

Claude Code (.mcp.json or claude mcp add):

{
  "mssql-local": {
    "type": "stdio",
    "command": "node",
    "args": [
      "/path/to/mssql-mcp-server/build/index.js",
      "--connection-string", "Server=localhost,1433;Database=MyDb;User Id=app;Password=***;Encrypt=true;TrustServerCertificate=true",
      "--security-mode", "unsafe", "--allow-destructive"
    ]
  }
}

VS Code (mcp.json):

{
  "servers": {
    "mssql-local": {
      "type": "stdio",
      "command": "node",
      "args": [
        "/path/to/mssql-mcp-server/build/index.js",
        "--connection-string", "Server=localhost,1433;Database=MyDb;User Id=app;Password=***;Encrypt=true;TrustServerCertificate=true",
        "--security-mode", "unsafe", "--allow-destructive"
      ]
    }
  }
}

Azure SQL Database, read-only — the default --security-mode is already readonly, so it does not need to be passed explicitly; shown here for clarity:

{
  "mssql-azure": {
    "type": "stdio",
    "command": "node",
    "args": [
      "/path/to/mssql-mcp-server/build/index.js",
      "--connection-string", "Server=<server>.database.windows.net,1433;Database=MyDb;User Id=app;Password=***;Encrypt=true;TrustServerCertificate=false",
      "--security-mode", "readonly"
    ]
  }
}

Replace every placeholder (<server>.database.windows.net, MyDb, app, ***) with real values — never commit real credentials.

Connection strings may also be the ADO form shown above or a mssql:// URL (mssql://user:pass@host:1433/db?encrypt=true&trustServerCertificate=true); the server translates URL form itself (the underlying mssql driver only parses the ADO form).

Related MCP server: mcp-server-mssql

Security modes

Every tool call is classified into a risk category and checked against the server's --security-mode (default readonly) before it runs. destructive: true classifications additionally require --allow-destructive regardless of mode.

Mode

Allowed risks

readonly

read

write

read, write

admin

read, write, ddl, role_admin, filesystem

unsafe

read, write, ddl, role_admin, filesystem, arbitrary_sql

  • arbitrary_sql always requires --allow-destructive as well as unsafe. A raw SQL fragment can contain any statement — a where of 1=1; DROP TABLE dbo.t -- on an mssql_execute_mutation update reaches the engine as a multi-statement batch — so every classification of risk arbitrary_sql is marked destructive, whatever produced it: where on execute_mutation/export_table_data/copy_between_databases, mssql_manage_query explain with analyze, a raw column default on manage_schema, a filtered-index where, a checkExpression, RLS predicates, and function/trigger bodies. In practice --security-mode unsafe on its own now grants nothing beyond admin; unsafe plus --allow-destructive is what enables raw SQL.

  • --allow-destructive — permits classifications marked destructive (drop/delete/truncate/revoke/disable/reset-style operations, and every arbitrary_sql operation above), on top of whatever the mode already allows. Several argument flags additionally escalate an otherwise non-destructive operation into this category, because each one silently discards or disables something that already exists: replace: true on mssql_manage_functions create and on mssql_manage_triggers create (both emit CREATE OR ALTER, overwriting an existing body), replace: true on mssql_manage_rls create_policy (drops and recreates the policy and its predicate functions), and login: false on mssql_manage_users alter (ALTER LOGIN … DISABLE).

  • --allow-tool-connection-string — permits a tool call to supply its own connectionString (or, for mssql_copy_between_databases, sourceConnectionString/targetConnectionString) instead of using the server's configured connection. mssql_copy_between_databases has no server-string fallback at all — both connection strings are required tool arguments, so the tool cannot be used unless this flag is set.

A denied call returns isError: true with one of two messages, taken verbatim from src/security/policy.ts:

Blocked by MSSQL MCP security policy: <reason>. Current mode "readonly" allows read operations.

or, when the mode would allow the risk but the destructive flag is missing:

Blocked by MSSQL MCP security policy: <reason>. Destructive operations require --allow-destructive.

Every denial is written to stderr as a single JSON line prefixed [MCP Audit] and, if --audit-file is set, appended to that file:

[MCP Audit] {"event":"mssql_mcp.security","outcome":"denied","reason":"security_policy_denied","toolName":"mssql_execute_sql","operation":null,"securityMode":"readonly","allowDestructive":false,"risk":"arbitrary_sql","destructive":true,"timestamp":"2026-08-26T12:00:00.000Z"}

Allowed calls are recorded on the two channels differently, so the file can be a complete record without flooding the client's log:

  • --audit-file additionally records every allowed call whose risk is not read ("outcome":"allowed") — everything that could have changed state.

  • stderr carries an allowed call only when MSSQL_MCP_AUDIT_ALLOWED=true.

MSSQL_MCP_AUDIT_ALLOWED is an environment variable only — there is no corresponding CLI flag. Audit lines never carry tool arguments, only the tool name, operation, mode and classification.

Warning at startup: in --security-mode admin or unsafe without --workspace-dir, the server prints once to stderr

[MCP Warning] File tools are enabled without --workspace-dir; export/import/copy can read and write any path this process can access. Set --workspace-dir to sandbox them.

Configuration

Option

Env

Default

Meaning

-cs, --cs, --connection-string <string>

MSSQL_CONNECTION_STRING

—

Server-level connection string (ADO or mssql:// URL)

--security-mode <mode>

MSSQL_MCP_SECURITY_MODE

readonly

readonly | write | admin | unsafe

--allow-destructive

MSSQL_MCP_ALLOW_DESTRUCTIVE=true

false

Permit drop/delete/truncate/revoke/disable/reset operations

--allow-tool-connection-string

MSSQL_MCP_ALLOW_TOOL_CONNECTION_STRING=true

false

Permit connectionString / sourceConnectionString / targetConnectionString tool arguments

-tc, --tc, --tools-config <path>

MSSQL_MCP_TOOLS_CONFIG

—

JSON { "enabledTools": [...] } allow-list; see tools-config.readonly.json

--workspace-dir <dir>

MSSQL_MCP_WORKSPACE_DIR

—

If set, export/import paths must resolve inside it; relative paths resolve against it

--max-file-bytes <n>

MSSQL_MCP_MAX_FILE_BYTES

104857600 (100 MiB)

Export/import size cap in bytes

--audit-file <path>

MSSQL_MCP_AUDIT_FILE

—

Append JSON audit events to this file

--default-schema <name>

MSSQL_MCP_DEFAULT_SCHEMA

dbo

Fallback for every schema parameter

-V, --version, -h, --help

-cs/-tc are rewritten to --connection-string/--tools-config before argument parsing (Commander v15 rejects multi-character short flags outright); --cs/--tc are additionally registered as ordinary long-form aliases, so -cs, --cs and --connection-string are all equivalent (likewise -tc/--tc/--tools-config).

An invalid --security-mode exits with status 1 and prints:

securityMode must be one of readonly, write, admin, or unsafe.

Connection-string precedence (checked in this order): a tool-supplied connectionString (only when --allow-tool-connection-string is set) → --connection-string → MSSQL_CONNECTION_STRING → if none is set:

No connection string provided. Provide one in the tool arguments (requires --allow-tool-connection-string), via the --connection-string CLI option, or set the MSSQL_CONNECTION_STRING environment variable.

Tools config: if --tools-config points at a file with an enabledTools array, only those tools are registered; unknown names log [MCP Warning] Tool "<n>" specified in config file but not found in available tools.; calling a known-but-disabled tool returns Error: Tool "<name>" is available but not enabled by the current server configuration.

The allow-list fails closed: a file that cannot be read or is not { "enabledTools": string[] } stops the server rather than quietly enabling every tool, printing one of

[MCP Error] Could not read tools configuration file at <path>: <reason>
[MCP Error] Invalid tools configuration file format at <path>: expected { "enabledTools": string[] }

and exiting with status 1 before it serves anything.

Tools

All 18 tools are prefixed mssql_. Full parameter tables (types, defaults, whether each field is required) are generated from the server's own schemas in TOOL_SCHEMAS.md — run npm run docs to regenerate it after changing a tool's inputSchema.

Tool

Summary

mssql_execute_query

Run a read-only SELECT/WITH query: select, count, or exists

mssql_execute_mutation

insert / update / delete / upsert (MERGE) against one table

mssql_execute_sql

Run arbitrary T-SQL, including multi-batch scripts (GO) and transactions

mssql_manage_schema

Inspect tables, create/alter tables, manage enum-style CHECK constraints

mssql_manage_indexes

List, create, drop, rebuild/reorganize, and analyze index usage

mssql_manage_constraints

List, create/drop primary key, unique, check and foreign key constraints

mssql_manage_functions

List, create, drop scalar/table-valued functions and stored procedures

mssql_manage_triggers

List, create, drop, enable/disable DML triggers

mssql_manage_rls

Row-Level Security policies backed by generated predicate functions

mssql_manage_users

Logins/users, role membership, grant/revoke permissions

mssql_manage_comments

Object/column descriptions stored as MS_Description extended properties

mssql_manage_query

Execution plans, slow-query and statistics reporting, stats reset

mssql_analyze_database

Configuration, performance and security analysis with recommendations

mssql_debug_database

Diagnose connection, performance, lock and replication issues

mssql_monitor_database

Point-in-time database/table/query/lock/replication metrics and alerts

mssql_export_table_data

Stream a table (optionally filtered) to a local JSON or CSV file

mssql_import_table_data

Bulk-load a local JSON or CSV file into a table, inside one transaction

mssql_copy_between_databases

Stream rows from a table in one database into the same table in another

Query execution notes

  • mssql_execute_query runs exactly one SELECT/WITH statement. T-SQL does not need a ; between statements, so a second one can simply be appended to a query — SELECT 1 AS a USE master ran both and left the pooled session in master for every later call. Four rules enforce the single statement. The first three are applied to the query with the contents of string literals, comments and bracketed/quoted identifiers blanked out (so [Set], "Use" and '… use master' are data, not keywords); the fourth is a runtime check. Masking follows the engine's own lexing: a -- comment ends at the first carriage return or newline (SELECT 1 AS a --\rUSE master is not one long comment), block comments nest (/* a /* b */ c */ is blanked whole), and the delimiters ', ", [, ] are left in place so a blanked literal cannot be mistaken for "nothing was here":

    1. Statement keywords are rejected anywhere in the query: USE, SET, DECLARE, BEGIN, WHILE, IF, GOTO, RETURN, PRINT, RAISERROR, THROW, COMMIT, ROLLBACK, SAVE, OPEN, CLOSE, DEALLOCATE, RECONFIGURE, CHECKPOINT, BREAK, CONTINUE, DISABLE, ENABLE, RECEIVE, SEND, REVERT, ADD, alongside the data-changing set (INSERT/UPDATE/DELETE/MERGE/INTO/EXEC/DDL/DBCC/WAITFOR/WRITETEXT/UPDATETEXT/READTEXT/SETUSER).

    2. Multi-word phrases whose individual words must stay legal on their own: END CONVERSATION, MOVE CONVERSATION, GET CONVERSATION (a bare END still closes a CASE), and NEXT VALUE FOR — the one read-shaped expression that changes persistent state, because it advances a SEQUENCE (FETCH NEXT, (VALUES …), FOR XML and a column named next_value are all unaffected).

    3. Structure: exactly one statement SELECT — the first SELECT at bracket depth 0 (for a WITH query, the outer one after the CTE list). Any other SELECT must either sit inside brackets (a subquery, derived table, CTE body, EXISTS/IN, APPLY) or directly follow UNION/UNION ALL/EXCEPT/INTERSECT. A ( at depth 0 that opens a bracketed SELECT is itself only accepted where a subquery belongs — after a set operator, IN/EXISTS/ANY/ALL, FROM/JOIN/APPLY/AS/WHERE/ON, a comparison operator, a comma or another ( — so SELECT 1 AS a (SELECT DB_NAME()), which SQL Server runs as two statements, is rejected. Anything that fails these is query must contain exactly one statement.

    4. Result-set count, checked while the query runs. Every streamed path (select, and the count/exists fallbacks) refuses the query the moment the engine announces a second result set — query produced more than one result set; only a single SELECT statement is allowed — cancelling the request and returning that error instead of rows. This is what catches SELECT 1 AS a ((SELECT DB_NAME())), where the smuggled SELECT is bracketed and so indistinguishable, token by token, from the subquery in ISNULL((SELECT 1), 0). Precisely: a second SELECT smuggled inside doubled parentheses is refused when the engine announces its result set; if a row limit cancels the request before that happens, the smuggled statement may already have started executing server-side — it cannot return rows to the caller and, because the validator rejects every statement keyword and the NEXT VALUE FOR construct, it cannot change database or session state. (The limit cancels as soon as a row beyond it arrives and the driver announces nothing afterwards; draining the whole first result set so the guard always fires would turn every limited readonly select into a full scan.) Subqueries, IN (SELECT …), EXISTS (SELECT …), CTEs (including recursive ones), CROSS APPLY, derived tables, (VALUES …) with an alias column list, UNION [ALL]/EXCEPT/INTERSECT, CASE … END, OFFSET … FETCH NEXT, WITH (NOLOCK)/WITH TIES, OPENJSON … WITH, GROUPING SETS, FOR XML/FOR JSON, OPTION (RECOMPILE), IIF, DATEADD and columns such as EndDate/BeginDate/Settings/Address/EndConversation all still work. Rules 1–3 are a keyword and structure scan, not a T-SQL parser, and they err towards rejection: an unbracketed column literally named Open, Close, Set or Use is rejected — bracket it. Use mssql_execute_sql (unsafe + --allow-destructive) for anything else.

  • mssql_execute_query's select operation accepts an optional limit, and defaults to 10000 rows when it is omitted; when the limit is reached the tool cancels the underlying request and returns exactly the rows collected so far. The success message then reads Query executed successfully. Retrieved <n> rows. Row limit of <limit> reached; more rows may exist. — that second sentence is added only when a row beyond the limit actually arrived, so a result of exactly limit rows never claims rows were left behind. count and exists are unaffected (they never materialise rows).

  • mssql_execute_sql has no row limit or limit parameter at all; it returns every row every batch produces.

Export, import and copy

  • CSV parsing is strict, not lenient. A " only opens quoted-field mode at the very start of a field; a " appearing elsewhere in an unquoted field is a literal character; a quoted field left open at end-of-file throws Unterminated quoted field in CSV input rather than silently merging the rest of the file into one record.

  • mssql_import_table_data requires a JSON file to contain a top-level array of objects (Input file does not contain an array of records otherwise). Two input columns that collapse to the same table column case-insensitively (e.g. Name and name) are rejected as Column <c> is specified more than once. time columns are coerced from a bare HH:MM:SS[.fff] string by anchoring it to 1970-01-01 in UTC; a cell that cannot be coerced to its column's type (an unparsable number, date, or hex binary value) is rejected with Column <c>: cannot coerce "<v>" to <type> instead of reaching the driver as an opaque error or silently loading as NULL/zero.

  • Computed and rowversion/timestamp columns are skipped, on both mssql_import_table_data and mssql_copy_between_databases: SQL Server refuses a supplied value for them (error 271), so any such column present in the input file or on the source table is dropped from the load and the target engine computes or stamps the value itself. This is silent — it is never reported as a missing or unknown column.

  • Rows without an identity-column value present in the data are loaded through mssql's bulk sql.Table path with checkConstraints: true and fireTriggers: true — CHECK/FK constraints are enforced and INSERT triggers fire, just as they would for an ordinary INSERT. Rows whose data does include identity-column values are loaded instead via SET IDENTITY_INSERT ON and batched multi-row INSERT statements. mssql_copy_between_databases reuses the same loader on the target side.

  • mssql_export_table_data never damages an existing file. Exporting to a path that already exists is an error — Output file already exists: <path>. Pass overwrite: true to replace it. — unless you pass overwrite: true. Either way rows are streamed into a temp file (<outputPath>.<pid>.<timestamp>.tmp) alongside the target and renamed onto it only once the export completed; if it fails partway (a permission error, a query error mid-stream, or the size cap being hit) only the temp file is removed, so the previous contents are still there and no corrupt/truncated file is left behind.

  • CSV exports neutralise spreadsheet formulas. A string cell whose text starts with =, +, -, @, a tab or a carriage return, and does not look like a number, is written with a leading ' so Excel/Sheets treat it as text rather than evaluating it. Numeric-looking strings (-5, +62812) and real numbers are untouched, and mssql_import_table_data does not strip the quote — the exported file is the record.

  • A cell that cannot be coerced on import is reported with at most 40 characters of its value (Column Qty: cannot coerce "…" to int), so an error message and its [MCP Error] log line never carry a whole cell.

  • File paths for export/import: when --workspace-dir is set, every resolved path must stay inside it (segment-based .. and absolute-outside-workspace checks — Path "<path>" is outside the workspace directory.); a size cap from --max-file-bytes applies to both the source file being read (File exceeds max file size of <n> bytes.) and the file being written (Generated export exceeds max file size of <n> bytes.); only .json/.csv extensions matching the requested format are accepted.

PostgreSQL → SQL Server differences

Because the tool surface mirrors a Postgres server, several tools map a Postgres concept onto a different SQL Server mechanism:

Postgres concept

SQL Server equivalent used here

ENUM types

mssql_manage_schema's get_enums/create_enum operations read and write IN-list CHECK constraints (sys.check_constraints) — there is no native SQL Server enum type

Row-level triggers, BEFORE/WHEN

SQL Server triggers are statement-level only; mssql_manage_triggers rejects forEach: "ROW", timing: "BEFORE" (use INSTEAD OF), a TRUNCATE event, and a when clause, each with an explanatory error

CREATE POLICY ... USING/WITH CHECK

mssql_manage_rls compiles the using/check predicates into schema-bound inline table-valued functions and wires them into a CREATE SECURITY POLICY ... ADD FILTER/BLOCK PREDICATE

Roles

mssql_manage_users creates a server LOGIN plus a database USER (or a contained USER when userType is contained, the default on Azure SQL Database) rather than a single Postgres role

COMMENT ON ...

mssql_manage_comments reads/writes the MS_Description extended property via sp_addextendedproperty/sp_updateextendedproperty/sp_dropextendedproperty and fn_listextendedproperty

EXPLAIN [ANALYZE]

mssql_manage_query's explain operation uses `SET SHOWPLAN_XML

pg_stat_statements

get_slow_queries/get_stats/reset_stats read from Query Store when it is enabled and in a read-write state, otherwise fall back to the plan cache (sys.dm_exec_query_stats)

manage_users behaviour notes

  • drop always attempts DROP LOGIN for a login-type user once the database USER has been dropped, whenever a server login with that name exists — it does not check whether some other database on the instance still maps a user to that login. (Design note: the spec originally described a "no other database user maps to it" check; the shipped behaviour is the simpler unconditional drop, reported and accepted as the code of record.)

  • alter maps superuser/createrole to db_owner/db_securityadmin database-role membership on Azure SQL Database (and to the sysadmin/securityadmin server roles elsewhere), the same mapping create uses; createdb has no Azure SQL Database equivalent and is reported under unsupported instead of being applied.

Authentication

Connection strings accept:

  • SQL authentication: User Id=...;Password=... (SQL login or Azure AD login with a password).

  • Azure AD: Authentication=Active Directory Password (with User Id/Password) or Authentication=Active Directory Default (uses the ambient Azure identity).

  • NTLM: Authentication=NTLM;Domain=CORP with User Id/Password.

  • Windows integrated authentication (SSPI) is not supported. The underlying driver (tedious) cannot do it; use a SQL login, NTLM with explicit credentials, or Azure AD instead.

Development

npm test              # unit + integration (integration skipped without MSSQL_TEST_CONNECTION_STRING)
npm run test:unit
npm run test:integration
npm run typecheck
npm run docs           # regenerate TOOL_SCHEMAS.md

Integration tests need a local SQL Server instance and a dedicated login. .env.test (gitignored) supplies MSSQL_TEST_CONNECTION_STRING. The login is created once with a generated password (PowerShell, run against localhost\SQLEXPRESS with Windows auth):

$pw = -join ((48..57 + 65..90 + 97..122) | Get-Random -Count 24 | ForEach-Object { [char]$_ }) + 'aZ9!'
sqlcmd -S "localhost\SQLEXPRESS" -E -Q "IF NOT EXISTS (SELECT 1 FROM sys.server_principals WHERE name = 'mssql_mcp_test') BEGIN CREATE LOGIN [mssql_mcp_test] WITH PASSWORD = N'$pw', CHECK_POLICY = OFF; ALTER SERVER ROLE [sysadmin] ADD MEMBER [mssql_mcp_test]; END ELSE ALTER LOGIN [mssql_mcp_test] WITH PASSWORD = N'$pw';"
"MSSQL_TEST_CONNECTION_STRING=Server=localhost,1433;Database=master;User Id=mssql_mcp_test;Password=$pw;Encrypt=true;TrustServerCertificate=true" | Set-Content -Encoding utf8 .env.test

.env.test is gitignored; never commit or print its contents.

Known limitations

  • No Windows integrated auth.

  • OUTPUT on tables with triggers (returning in mutations) fails with SQL Server error 334.

  • ONLINE = ON index operations need Enterprise/Azure; Express returns an error.

  • count/exists on queries with ORDER BY but no TOP fall back to client-side streaming.

  • Query Store statistics require Query Store to be enabled; plan-cache statistics are lost on restart / DBCC FREEPROCCACHE.

  • rolledBack transaction count is not exposed by SQL Server DMVs and is always null.

  • Computed and rowversion/timestamp columns are skipped on import and copy (SQL Server error 271 forbids supplying a value for them); the target engine assigns them.

  • Symlinks and junctions inside --workspace-dir are followed: the sandbox validates the path you pass, not where a link inside the workspace points. Do not place links to sensitive locations in a workspace directory.

  • INSTEAD OF triggers defined on views are not listed by mssql_manage_triggers get and cannot be toggled with set_state — both work through sys.tables and ALTER TABLE … ENABLE|DISABLE TRIGGER.

  • The read-only validator for mssql_execute_query is a keyword and structure scan over masked SQL, not a T-SQL parser, and errs on the side of rejection: an unbracketed column named Open, Close, Set, Use, Save, Send or Return is refused — bracket it ([Open]) or alias it. (Add is not affected: ADD is reserved in T-SQL, so it can never be an unbracketed column name.)

  • mssql_export_table_data checks that the output path does not exist and later renames its temp file onto it; those two steps are not atomic, so a file created by another process in between is replaced. The check guards against overwriting a file that was already there, not against a concurrent writer.

  • Without --workspace-dir, the file tools in admin/unsafe can read and write anywhere the server process can reach; you are warned once at startup.

  • Pools created from tool-supplied connection strings are closed after 60 seconds idle (swept every 15 seconds), measured from the last request issued on them and never while a request is in flight; the server's own --connection-string pool is never evicted. A call after eviction simply reconnects.

Available Tools

18 tools
mssql_analyze_databaseC

Analyze SQL Server database configuration and performance

Inputs: schema, analysisType, connectionString.

mssql_copy_between_databasesC

Copy data between two SQL Server databases

Inputs: tableName (required), sourceConnectionString (required), targetConnectionString (required), where, +3 more.

mssql_debug_databaseC

Debug common SQL Server issues

Inputs: issue (required), logLevel, connectionString.

mssql_execute_mutationB

Execute data modification operations (INSERT/UPDATE/DELETE/UPSERT) - operation="insert/update/delete/upsert" with table and data. Examples: operation="insert", table="Users", data={"Name":"John","Email":"john@example.com"}

Inputs: table (required), operation (required), data, where, +5 more.

mssql_execute_queryA

Execute SELECT queries and data retrieval operations - operation="select/count/exists" with query and optional parameters. Examples: operation="select", query="SELECT * FROM Users WHERE CreatedAt > @p1", parameters=["2024-01-01"]

Inputs: query (required), operation (required), limit, timeout, +2 more.

mssql_execute_sqlA

Execute arbitrary T-SQL - sql="ANY_VALID_TSQL" with optional parameters, GO batch separators and transaction support. Examples: sql="CREATE INDEX ...", sql="WITH cte AS (...) SELECT ...", transactional=true

Inputs: sql (required), timeout, expectRows, parameters, +2 more.

mssql_export_table_dataB

Export table data to JSON or CSV format

Inputs: tableName (required), outputPath (required), limit, where, +5 more.

mssql_import_table_dataC

Import data from JSON or CSV file into a table

Inputs: inputPath (required), tableName (required), format, schema, +4 more.

mssql_manage_commentsA

Manage SQL Server object descriptions (MS_Description extended properties) - get, set, remove comments on tables, columns, functions, and other objects. Examples: operation="get" with objectType="table", objectName="Users", operation="set" with comment text, operation="bulk_get" for discovery

Inputs: operation (required), schema, comment, tableName, +6 more.

mssql_manage_constraintsA

Manage SQL Server constraints - get, create foreign keys, drop foreign keys, create constraints, drop constraints. Examples: operation="get" to list constraints, operation="create_fk" with constraintName, tableName, columnNames, referencedTable, referencedColumns

Inputs: operation (required), schema, cascade, ifExists, +15 more.

mssql_manage_functionsA

Manage SQL Server functions and stored procedures - get, create, or drop with a single tool. Examples: operation="get" to list, operation="create" with functionName="fn_total", parameters="@price DECIMAL(10,2), @tax DECIMAL(5,2)", returnType="DECIMAL(10,2)", functionBody="RETURN @price + (@price * @tax)"

Inputs: operation (required), schema, cascade, replace, +10 more.

mssql_manage_indexesB

Manage SQL Server indexes - get, create, drop, rebuild/reorganize, and analyze usage with a single tool. Examples: operation="get" to list indexes, operation="create" with indexName, tableName, columns, operation="analyze_usage" for performance analysis

Inputs: operation (required), mode, type, where, +17 more.

mssql_manage_queryB

Manage SQL Server query analysis and performance - operation="explain" for execution plans, operation="get_slow_queries" for slow query analysis (Query Store or plan cache), operation="get_stats" for query statistics, operation="reset_stats" for clearing statistics

Inputs: operation (required), costs, limit, query, +11 more.

mssql_manage_rlsB

Manage SQL Server Row-Level Security - security policies with generated predicate functions. Examples: operation="create_policy" with tableName, policyName, predicateColumns=["TenantId"], using="@TenantId = CAST(SESSION_CONTEXT(N'TenantId') AS int)"

Inputs: operation (required), role, check, roles, +9 more.

mssql_manage_schemaA

Manage SQL Server schema - get schema info, create/alter tables, manage enum-style CHECK constraints. Examples: operation="get_info" for table lists, operation="create_table" with tableName and columns, operation="get_enums" to list IN-list CHECK constraints, operation="create_enum" with enumName, tableName, columnName and values

Inputs: operation (required), schema, values, columns, +6 more.

mssql_manage_triggersA

Manage SQL Server DML triggers - get, create, drop, and enable/disable triggers. Examples: operation="get" to list triggers, operation="create" with triggerName, tableName and triggerBody (or functionName to EXEC a procedure), operation="set_state" with triggerName, tableName, enable

Inputs: operation (required), when, enable, events, +11 more.

mssql_manage_usersA

Manage SQL Server logins, database users and permissions - create, drop, alter users, grant/revoke permissions. Examples: operation="create" with username="app_user", password="...", operation="grant" with username, permissions, target, targetType

Inputs: operation (required), login, schema, target, +17 more.

mssql_monitor_databaseC

Get real-time monitoring information for a SQL Server database

Inputs: schema, includeLocks, includeTables, includeQueries, +3 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.3/5.0

    Scored across 18 tools

    Disambiguation3/5

    Most tools target distinct resources (indexes, constraints, triggers, users), but there is overlap among execute_query, execute_mutation, and execute_sql, and between analyze_database, monitor_database, debug_database, and manage_query for performance/diagnostic work. Descriptions help somewhat, but an agent could still pick the wrong tool for custom T-SQL or monitoring.

    Naming Consistency5/5

    All tools follow the mssql_<verb>_<object> snake_case pattern with predictable verbs like execute, manage, analyze, export, import, and copy. The naming is highly consistent and easy to navigate.

    Tool Count4/5

    18 tools is slightly above the typical 3-15 well-scoped range, but the broad SQL Server administration scope justifies most entries. Each tool encapsulates a meaningful subdomain, so the count is reasonable if a bit heavy.

    Completeness4/5

    The surface covers data operations, schema, indexes, constraints, functions/procedures, triggers, RLS, users, comments, query performance, import/export, and database copying. Dedicated backup/restore and database-level lifecycle tools are missing, though arbitrary T-SQL via mssql_execute_sql provides a workaround.

    Maintenance

    ActivityNo data
    ResponsivenessSyncing

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      Not graded
      maintenance
      Enables AI assistants to interact with both local SQL Server and Azure SQL Database through natural language, supporting queries, data manipulation, and schema operations with built-in security features.
      8
      2,310 npm
      1
      -
    • A
      license
      B
      quality
      D
      maintenance
      Enables AI agents to interact with Microsoft SQL Server databases via MCP, supporting table listing, schema retrieval, and CRUD operations.
      3
      1
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables AI assistants to connect to Microsoft SQL Server via the MCP protocol, supporting database schema queries, data reading, and arbitrary SQL execution.
      ISC
    • A
      license
      B
      quality
      C
      maintenance
      Enables AI assistants to connect to Microsoft SQL Server for schema discovery, querying, stored procedures, DDL, performance diagnostics, and developer utilities with configurable security modes.
      35
      40 npm
      MIT