Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/A-Point-Systems-ltd/ms-sql-mcp/llms.txt

Use this file to discover all available pages before exploring further.

ReadData is the single entry point for every query that returns rows from the connected SQL Server or Azure SQL Database. Pass any valid read-only T-SQL SELECT statement — including queries against user tables, catalog views (sys.*), INFORMATION_SCHEMA, and dynamic management views — and receive the result set as an array of row objects keyed by column name. ExecuteSQL explicitly rejects SELECT and read-only CTEs. Do not attempt to run queries through ExecuteSQL; always use ReadData for anything that reads data.

Parameter

sql
string
required
A single read-only T-SQL statement. Both forms below are accepted:
  • A plain SELECT statement.
  • A WITH … SELECT CTE whose final statement is a SELECT (common table expressions).
The statement is validated by SqlStatementClassifier before execution. Only one statement is allowed per call — batch separators (GO) and internal semicolons between statements are rejected.

Routing rules — accepted vs. rejected

InputVerdictReason
SELECT …✅ AcceptedStandard read-only query.
WITH cte AS (…) SELECT …✅ AcceptedCTE that culminates in a SELECT.
SELECT … INTO #tmp❌ RejectedSELECT … INTO writes a new table; use ExecuteSQL.
WITH cte AS (…) INSERT …❌ RejectedMutating CTE; use ExecuteSQL.
INSERT / UPDATE / DELETE / MERGE❌ RejectedDML; use ExecuteSQL.
CREATE / ALTER / DROP / TRUNCATE❌ RejectedDDL; use ExecuteSQL.
EXEC / EXECUTE❌ RejectedProcedural; use ExecuteSQL.
Two statements separated by ;❌ RejectedOnly a single statement is allowed.
When a rejected input is submitted, ReadData returns:
ReadData accepts only read-only SELECT queries (including WITH ... SELECT).
Use ExecuteSQL for DDL/DML and SELECT ... INTO.
When a SELECT is mistakenly submitted to ExecuteSQL, that tool returns:
ExecuteSQL does not allow SELECT or other read-only queries.
Use ReadData for all SELECT statements, including sys.*, INFORMATION_SCHEMA, and DMVs.

Returns

data
array
Array of row objects. Each object is a dictionary keyed by the column name as it appears in the result set (column alias if specified, otherwise the column name from the source table or expression).

Usage notes

SQL parameters are not supported — the server executes the SQL string verbatim. Build literal values directly into your query string. Never interpolate untrusted user input into a ReadData call; doing so creates a SQL injection risk.
For single-object schema exploration, prefer the dedicated tools — DescribeTable, DescribeView, and GetObject — over custom sys.* queries. They return richer structured data with fewer round-trips. Reserve ReadData for ad-hoc queries, cross-object joins, and catalog investigations that the dedicated tools don’t cover.
Column names in the result are taken directly from the SQL Server result-set metadata. If a query selects two columns with the same name (common with SELECT * joins), the later column’s value overwrites the earlier one in the row dictionary. Use explicit column aliases to avoid collisions.

Examples

Query system catalog — list tables modified today

{
  "tool": "ReadData",
  "arguments": {
    "sql": "SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND CAST(OBJECTPROPERTYEX(OBJECT_ID(TABLE_SCHEMA + '.' + TABLE_NAME), 'SchemaId') AS INT) IS NOT NULL ORDER BY TABLE_SCHEMA, TABLE_NAME"
  }
}

Query sys.tables

{
  "tool": "ReadData",
  "arguments": {
    "sql": "SELECT s.name AS schema_name, t.name AS table_name, t.create_date, t.modify_date FROM sys.tables t INNER JOIN sys.schemas s ON t.schema_id = s.schema_id ORDER BY s.name, t.name"
  }
}

Response

{
  "success": true,
  "data": [
    {
      "schema_name": "dbo",
      "table_name": "Customers",
      "create_date": "2023-09-01T11:00:00",
      "modify_date": "2024-01-10T08:30:00"
    },
    {
      "schema_name": "dbo",
      "table_name": "OrderItems",
      "create_date": "2023-09-01T11:05:00",
      "modify_date": "2024-01-10T08:30:00"
    },
    {
      "schema_name": "dbo",
      "table_name": "Orders",
      "create_date": "2023-09-01T11:02:00",
      "modify_date": "2024-06-15T14:22:00"
    }
  ]
}

CTE query example

{
  "tool": "ReadData",
  "arguments": {
    "sql": "WITH TopCustomers AS (SELECT TOP 5 CustomerId, COUNT(*) AS OrderCount FROM dbo.Orders GROUP BY CustomerId ORDER BY OrderCount DESC) SELECT c.FullName, tc.OrderCount FROM TopCustomers tc INNER JOIN dbo.Customers c ON tc.CustomerId = c.CustomerId"
  }
}

NULL values in response

SQL NULL database values are serialized as JSON null:
{
  "success": true,
  "data": [
    {
      "OrderId": 1001,
      "ShippedDate": null,
      "TotalAmount": 149.99
    }
  ]
}

Build docs developers (and LLMs) love