Azure SQL MCP Server
README.md
# Azure SQL MCP Server
A Model Context Protocol (MCP) server for connecting to Azure SQL databases. This server provides tools to query, explore, and interact with Azure SQL databases through Claude Desktop or any MCP-compatible client.
## Features
- Execute arbitrary SQL queries
- Browse database tables and schemas
- Get sample data from tables
- Configuration validation
- Azure Active Directory authentication via DefaultAzureCredential
## Prerequisites
Before starting, ensure you have these installed:
- **Python 3.11+** - Managed via [pyenv](https://github.com/pyenv/pyenv) (recommended) or system Python
- **Node.js 18+** - For MCP Inspector ([Download](https://nodejs.org/))
- **uv** - Fast Python package manager ([Install guide](https://github.com/astral-sh/uv))
- **ODBC Driver 17 for SQL Server** - ([Download](https://learn.microsoft.com/en-us/sql/connect/odbc/download-odbc-driver-for-sql-server))
- **Azure credentials** - Azure CLI, VS Code, or Managed Identity
- **npx** - Comes with Node.js (used to run MCP Inspector)
### Installing Prerequisites
#### Install Node.js and npx
```bash
# Windows: Download from https://nodejs.org/
# Or use winget
winget install OpenJS.NodeJS
# macOS
brew install node
# Linux
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
# Verify installation
node --version
npx --version
```
#### Install uv
```bash
# Windows (PowerShell)
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Verify installation
uv --version
```
#### Install pyenv (Optional but Recommended)
```bash
# Windows
# Use pyenv-win: https://github.com/pyenv-win/pyenv-win
# macOS
brew install pyenv
# Linux
curl https://pyenv.run | bash
```
## Installation & Setup
### 1. Clone the Repository
```bash
git clone <your-repo-url>
cd mcp_component
```
### 2. Set Python Version (if using pyenv)
```bash
# Set global Python version
pyenv global 3.11.4
# Or set local version for this project only
pyenv local 3.11.4
# Verify
python --version
```
### 3. Create and Activate Virtual Environment
```bash
# Create virtual environment using uv
uv venv
# Activate the virtual environment
# Windows (PowerShell)
.venv\Scripts\activate
# Windows (CMD)
.venv\Scripts\activate.bat
# macOS/Linux
source .venv/bin/activate
```
### 4. Install Dependencies
```bash
# Option 1: Sync from pyproject.toml (recommended)
uv sync
# Option 2: Install from requirements.txt
uv pip install -r requirements.txt
uv add -r requirements.txt
# Verify installation
uv pip list
```
> **Pro Tip:** If you need to add new packages later:
> ```bash
> # Add a single package
> uv add package-name
>
> # Add multiple packages from requirements.txt
> uv add -r requirements.txt
> ```
### 5. Configure Environment Variables
Create a `.env` file in the project root:
```bash
# Copy the example
cp .env.example .env
# Or create manually
```
Edit `.env` with your Azure SQL credentials:
```env
SERVER_NAME=your-server.database.windows.net
DATABASE=your-database-name
```
**Example:**
```env
SERVER_NAME=mycompany-sql.database.windows.net
DATABASE=Northwind
```
> **Note:** You can test the server without a real database! Leave the default values to test the MCP server functionality. The tools will indicate configuration is needed, but the server will run fine.
### 6. Authenticate with Azure
Make sure you're authenticated with Azure using one of these methods:
```bash
# Option 1: Azure CLI (recommended for local testing)
az login
# Option 2: Use environment variables
# Add to .env file:
# AZURE_TENANT_ID=your-tenant-id
# AZURE_CLIENT_ID=your-client-id
# AZURE_CLIENT_SECRET=your-client-secret
# Option 3: Use VS Code Azure Account extension
# (automatically works if signed in)
```
Verify Azure authentication:
```bash
az account show
```
## Testing with MCP Inspector
The MCP Inspector is an interactive tool for testing your MCP server before connecting it to Claude Desktop.
### Install and Run Inspector
```bash
# Run the inspector (npx will auto-install it if needed)
npx @modelcontextprotocol/inspector uv --directory . run server.py
```
**What happens:**
1. `npx` downloads and runs the MCP Inspector (first time only)
2. Opens automatically in your default browser at `http://localhost:5173`
3. Shows all available tools in the left sidebar
4. Displays request/response JSON for debugging
### Inspector Interface Overview
- **Left Panel:** List of available tools
- **Center Panel:** Tool parameters and execution
- **Right Panel:** JSON request/response output
- **Bottom:** Server logs and errors (stderr)
### Testing Workflow
1. **Start the Inspector** (command above)
2. **Check Configuration:**
- Click on `check_database_config` tool
- Click "Run Tool"
- Verify your database settings
3. **Test Tools:**
- Try `get_tables` to see available tables
- Use `get_table_schema` with a table name
- Execute `get_sample_data` to preview data
4. **Debug Issues:**
- Check the stderr output for error messages
- Verify your `.env` file is correct
- Ensure Azure authentication is working
### Available Tools
#### 1. `check_database_config`
Check if your database credentials are properly configured.
**No parameters required**
**Example Response:**
```json
{
"configured": true,
"message": "Configuration OK",
"server_name": "myserver.database.windows.net",
"database": "Northwind"
}
```
#### 2. `execute_query`
Execute any SQL query against your database.
**Parameters:**
- `query` (string): SQL query to execute
**Example:**
```json
{
"query": "SELECT TOP 5 * FROM Customers ORDER BY CompanyName"
}
```
**Response:**
```json
{
"rows": 5,
"columns": ["CustomerID", "CompanyName", "ContactName"],
"data": [...]
}
```
#### 3. `get_tables`
Get a list of all tables in the database.
**No parameters required**
**Example Response:**
```json
{
"tables": [
{
"schema": "dbo",
"name": "Customers",
"full_name": "dbo.Customers"
},
{
"schema": "dbo",
"name": "Orders",
"full_name": "dbo.Orders"
}
]
}
```
#### 4. `get_table_schema`
Get detailed schema information for a specific table.
**Parameters:**
- `table_name` (string): Name of the table (e.g., "Customers" or "dbo.Customers")
**Example:**
```json
{
"table_name": "Customers"
}
```
**Response:**
```json
{
"table": "Customers",
"columns": [
{
"COLUMN_NAME": "CustomerID",
"DATA_TYPE": "nchar",
"IS_NULLABLE": "NO",
"COLUMN_DEFAULT": null,
"CHARACTER_MAXIMUM_LENGTH": 5
}
]
}
```
#### 5. `get_sample_data`
Get sample rows from a table.
**Parameters:**
- `table_name` (string): Name of the table
- `limit` (integer, optional): Number of rows (default: 5, max: 100)
**Example:**
```json
{
"table_name": "Customers",
"limit": 10
}
```
**Response:**
```json
{
"table": "Customers",
"sample_rows": 10,
"total_columns": 11,
"columns": ["CustomerID", "CompanyName", ...],
"data": [...]
}
```
## Using with Claude Desktop
Once you've tested with the Inspector, connect to Claude Desktop:
### 1. Locate Claude Desktop Config
**Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
**Linux:** `~/.config/Claude/claude_desktop_config.json`
### 2. Add Server Configuration
Edit or create the config file:
**Windows:**
```json
{
"mcpServers": {
"azure-sql": {
"command": "uv",
"args": [
"--directory",
"C:\\Users\\YourUsername\\path\\to\\mcp_component",
"run",
"server.py"
]
}
}
}
```
**macOS/Linux:**
```json
{
"mcpServers": {
"azure-sql": {
"command": "uv",
"args": [
"--directory",
"/Users/yourname/projects/mcp_component",
"run",
"server.py"
]
}
}
}
```
> **Important:** Replace the path with your actual absolute project path!
### 3. Restart Claude Desktop
After saving the config:
1. **Completely quit** Claude Desktop (not just close the window)
2. Restart the application
3. Look for the **🔌 plug icon** in the interface
4. Click it to verify "azure-sql" server is connected (green indicator)
### 4. Test with Claude
Try asking Claude:
- "Can you check if my database is configured?"
- "What tables are available in my database?"
- "Show me the schema for the Customers table"
- "Get me 5 sample rows from the Orders table"
- "Execute this query: SELECT COUNT(*) FROM Products"
## Project Structure
```
mcp_component/
├── .env # Environment variables (create this - not in git)
├── .env.example # Example environment file
├── .gitignore # Git ignore rules
├── .python-version # Python version for pyenv
├── pyproject.toml # Project metadata and dependencies
├── requirements.txt # Python dependencies
├── uv.lock # Dependency lock file
├── server.py # Main entry point wrapper
├── mcp_server/
│ ├── __init__.py
│ └── server.py # MCP server implementation
├── README.md # This file
└── .venv/ # Virtual environment (created by uv venv)
```
## Troubleshooting
### "npx: command not found"
**Cause:** Node.js/npm is not installed or not in PATH
**Solution:**
```bash
# Verify Node.js installation
node --version
npm --version
# If not installed, install Node.js from https://nodejs.org/
# Or use a package manager (see Prerequisites section)
```
### "uv: command not found"
**Cause:** uv is not installed or not in PATH
**Solution:**
```bash
# Windows (PowerShell as Administrator)
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
# Then restart your terminal
# Verify
uv --version
```
### Inspector shows "error" notification
**Cause:** Server crashed during startup or has import errors
**Solution:**
1. Check the **stderr output** in the Inspector console for detailed error messages
2. Common issues:
- Python dependencies not installed: Run `uv sync`
- Wrong Python version: Run `python --version` (need 3.11+)
- Import errors: Make sure you're running from the project root
- Azure auth issues: Run `az login`
### "Database not configured" error
**Expected behavior** if you haven't set up your `.env` file with real credentials. The server will still run—you just won't be able to query data until you configure it.
**Solution:** Update `.env` with your actual Azure SQL Server details:
```env
SERVER_NAME=your-actual-server.database.windows.net
DATABASE=your-actual-database-name
```
### Connection timeout or authentication errors
**Solutions:**
1. **Firewall:** Verify your Azure SQL firewall allows your IP address
```bash
# Check current IP
curl https://api.ipify.org
# Add it to Azure SQL firewall rules in Azure Portal
```
2. **Authentication:** Run `az login` to authenticate
```bash
az login
az account show
```
3. **Permissions:** Check that your Azure account has access to the database
```bash
az sql db show --resource-group <rg-name> --server <server-name> --name <db-name>
```
4. **ODBC Driver:** Verify ODBC Driver 17 is installed
```powershell
# Windows - Check installed ODBC drivers
Get-OdbcDriver
# Should show "ODBC Driver 17 for SQL Server"
```
### Tools not appearing in Claude Desktop
**Solutions:**
1. **Config path:** Double-check the config file is in the correct location:
```powershell
# Windows - Open config directory
explorer %APPDATA%\Claude
# Verify claude_desktop_config.json exists
```
2. **Absolute path:** Ensure the project path in `args` is absolute and correct
```json
// ❌ Wrong - relative path
"C:\\mcp_component"
// ✅ Correct - absolute path
"C:\\Users\\YourName\\Projects\\mcp_component"
```
3. **Restart properly:** Completely quit Claude Desktop (not just minimize)
- Windows: Right-click system tray icon → Exit
- macOS: Cmd+Q or Claude → Quit Claude
4. **Check logs:** Look for errors in Claude Desktop logs:
- **Windows:** `%APPDATA%\Claude\logs`
- **macOS:** `~/Library/Logs/Claude`
5. **Test with Inspector first:** Verify the server works:
```bash
npx @modelcontextprotocol/inspector uv --directory . run server.py
```
### "ODBC Driver not found"
**Solution:** Install ODBC Driver 17 for SQL Server:
**Windows:**
```powershell
# Download and run installer from:
# https://go.microsoft.com/fwlink/?linkid=2249004
# Verify installation
Get-OdbcDriver | Where-Object {$_.Name -like "*SQL Server*"}
```
**macOS:**
```bash
brew tap microsoft/mssql-release https://github.com/Microsoft/homebrew-mssql-release
brew update
brew install msodbcsql17
# Verify
odbcinst -q -d
```
**Linux (Ubuntu/Debian):**
```bash
curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
curl https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/prod.list | sudo tee /etc/apt/sources.list.d/mssql-release.list
sudo apt-get update
sudo ACCEPT_EULA=Y apt-get install -y msodbcsql17
# Verify
odbcinst -q -d
```
### "Module not found" errors
**Solution:**
```bash
# Ensure virtual environment is activated
# Windows
.venv\Scripts\activate
# macOS/Linux
source .venv/bin/activate
# Reinstall dependencies
uv sync
# Or
uv pip install -r requirements.txt
```
## Development
### Adding Custom Tools
You can add your own tools to `mcp_server/server.py`:
```python
@mcp.tool()
async def my_custom_tool(param: str) -> str:
"""Description of what this tool does
Args:
param: Description of the parameter
"""
try:
engine = await get_azure_engine()
# Your custom logic here
query = text("SELECT * FROM MyTable WHERE column = :param")
with engine.connect() as connection:
result = connection.execute(query, {"param": param})
data = [dict(row) for row in result]
return json.dumps({"result": data}, indent=2)
except Exception as e:
return json.dumps({"error": str(e)}, indent=2)
```
**Best Practices:**
- Always wrap tools in try/except
- Return JSON strings (use `json.dumps()`)
- Use parameterized queries to prevent SQL injection
- Add descriptive docstrings for Claude to understand the tool
- Test new tools in the Inspector before using in Claude Desktop
### Updating Dependencies
```bash
# Add a new package
uv add package-name
# Update all packages
uv sync --upgrade
# Remove a package
uv remove package-name
```
## Authentication Details
This server uses `DefaultAzureCredential` from Azure Identity SDK, which tries multiple authentication methods in order:
1. **Environment variables** - `AZURE_TENANT_ID`, `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`
2. **Managed Identity** - Works automatically in Azure services (App Service, Functions, VMs)
3. **Azure CLI** - Uses `az login` credentials (✅ recommended for local development)
4. **Visual Studio Code** - Uses VS Code Azure Account extension
5. **Interactive browser** - Falls back to browser login
**For local testing (recommended):**
```bash
az login
```
**For production (recommended):**
- Use Managed Identity in Azure services
- Or use Service Principal with environment variables
## Contributing
Contributions are welcome! Please:
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/XXX-XXX`)
3. Make your changes
4. Test with the MCP Inspector
5. Commit your changes (`git commit -m 'Add XXXX feature'`)
6. Push to the branch (`git push origin feature/XXX-XXX`)
7. Open a Pull Request
## Resources
- **MCP Documentation:** https://modelcontextprotocol.io
- **MCP Inspector:** https://github.com/modelcontextprotocol/inspector
- **Azure SQL Documentation:** https://learn.microsoft.com/en-us/azure/azure-sql/
- **uv Documentation:** https://github.com/astral-sh/uv
- **FastMCP Documentation:** https://github.com/jlowin/fastmcp
TDQS
A3.7/5.0
Scored across 5 tools
Disambiguation5/5
Each tool serves a distinct function: config check, arbitrary query execution, listing tables, getting schema, and retrieving sample data. No two tools overlap in purpose.
Naming Consistency5/5
All tool names follow a consistent verb_noun pattern in snake_case (check_database_config, execute_query, get_sample_data, get_tables, get_table_schema), making the set predictable.
Tool Count5/5
Five tools cover essential database introspection and querying capabilities without unnecessary clutter, appropriate for a focused Azure SQL server.
Completeness4/5
Core operations are covered, but dedicated tools for data manipulation (insert/update/delete) or schema modification are missing, though these can be performed via execute_query. Minor gap.
Maintenance
ActivityInactive
ResponsivenessNo issues