azure-utils-mcp
# Azure Utils MCP Server
An MCP (Model Context Protocol) server for Azure development and operations. Compatible with any MCP client — Claude Code, Claude Desktop, Cursor, and others.
Covers three areas:
- **Cosmos DB** — list accounts, databases, and containers; run SQL queries; read, write, and delete documents
- **Service Bus** — list namespaces, queues, and topics; send messages; peek, purge, and requeue dead letter queues
- **Authorization / PIM** — list eligible roles and activate PIM role assignments
Authentication uses `DefaultAzureCredential`, which picks up an active `az login` session automatically. Optionally, Cosmos DB key-based auth and Service Bus connection-string auth can be used via environment variables (see [Authentication](#authentication) below).
## Requirements
- [uv](https://docs.astral.sh/uv/)
- [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) with an active `az login` session
## Installation
### macOS
```bash
brew install uv azure-cli
```
### Linux
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash # Debian/Ubuntu
```
For other Linux distributions see the [Azure CLI install docs](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli-linux).
### Windows
```powershell
winget install --id=astral-sh.uv
winget install --id=Microsoft.AzureCLI
```
## Configuration
**Claude Code** users:
```bash
claude mcp add --scope user azure-utils -- uvx azure-utils-mcp
```
For other MCP clients, add the following to your server configuration:
```json
{
"mcpServers": {
"azure-utils": {
"command": "uvx",
"args": ["azure-utils-mcp"]
}
}
}
```
Restart your MCP client after adding the server.
### Installing from source
```bash
git clone https://github.com/BrianDeacon/azure-utils-mcp
cd azure-utils-mcp
uv sync
az login
```
Then configure with the cloned path:
```json
{
"mcpServers": {
"azure-utils": {
"command": "uv",
"args": ["run", "--directory", "/path/to/azure-utils-mcp", "azure-utils-mcp"]
}
}
}
```
---
## Authentication
All tools default to `DefaultAzureCredential`, which picks up an active `az login` session, managed identity, or other standard Azure credential sources.
For Cosmos DB and Service Bus, you can optionally use key-based or connection-string auth by setting environment variables. Each tool accepts an optional parameter to specify which env var to read from, with sensible defaults:
| Service | Tool parameter | Default env var | What it holds |
|---------|---------------|-----------------|---------------|
| Cosmos DB | `key_env_var` | `AZURE_COSMOS_KEY` | Account key for data-plane operations |
| Service Bus | `connection_string_env_var` | `AZURE_SERVICEBUS_CONNECTION_STRING` | Connection string for data-plane operations |
If the specified environment variable is set, its value is used for authentication. If not, `DefaultAzureCredential` is used as a fallback.
This design lets you point different tool calls at different credentials by overriding the env var name. For example, you might use `MY_DEV_COSMOS_KEY` for one account and `MY_PROD_COSMOS_KEY` for another, keeping both in your environment without conflict.
Other environment variables:
- `AZURE_SUBSCRIPTION_ID` — used by `list_accounts` / `list_namespaces` if set; otherwise resolved from `az login`
---
## Cosmos DB Tools
The `account` parameter accepts either a short account name (e.g. `my-cosmos-account`) or a full endpoint URL. The `https://` prefix and `.documents.azure.com` suffix are added automatically if missing.
All Cosmos DB data-plane tools (everything except `cosmosdb_list_accounts`) accept an optional `key_env_var` parameter (default `AZURE_COSMOS_KEY`). See [Authentication](#authentication).
### `cosmosdb_list_accounts`
List all Cosmos DB accounts in the current Azure subscription.
### `cosmosdb_list_databases`
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `account` | string | yes | Cosmos DB account name or endpoint |
| `key_env_var` | string | no | Env var holding the account key (default `AZURE_COSMOS_KEY`) |
### `cosmosdb_list_containers`
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `account` | string | yes | Cosmos DB account name or endpoint |
| `database` | string | yes | Database name |
| `key_env_var` | string | no | Env var holding the account key (default `AZURE_COSMOS_KEY`) |
### `cosmosdb_get_container_info`
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `account` | string | yes | Cosmos DB account name or endpoint |
| `database` | string | yes | Database name |
| `container` | string | yes | Container name |
| `key_env_var` | string | no | Env var holding the account key (default `AZURE_COSMOS_KEY`) |
Returns partition key path, indexing policy, default TTL, unique key policy, and system properties.
### `cosmosdb_query_items`
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `account` | string | yes | Cosmos DB account name or endpoint |
| `database` | string | yes | Database name |
| `container` | string | yes | Container name |
| `query` | string | yes | SQL query (e.g. `SELECT * FROM c WHERE c.status = 'active'`) |
| `max_items` | integer | no | Max items to return (default 100, cap 1000) |
| `key_env_var` | string | no | Env var holding the account key (default `AZURE_COSMOS_KEY`) |
### `cosmosdb_query_items_to_file`
Same as `cosmosdb_query_items` but writes results to a file. Use when result sets may be large.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `account` | string | yes | Cosmos DB account name or endpoint |
| `database` | string | yes | Database name |
| `container` | string | yes | Container name |
| `query` | string | yes | SQL query |
| `output_file` | string | yes | Path to write results as a JSON array |
| `max_items` | integer | no | Max items to return (default 100, cap 1000) |
| `key_env_var` | string | no | Env var holding the account key (default `AZURE_COSMOS_KEY`) |
### `cosmosdb_count_items`
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `account` | string | yes | Cosmos DB account name or endpoint |
| `database` | string | yes | Database name |
| `container` | string | yes | Container name |
| `where` | string | no | SQL WHERE clause body (e.g. `c.status = 'active'`). If omitted, counts all items. |
| `key_env_var` | string | no | Env var holding the account key (default `AZURE_COSMOS_KEY`) |
### `cosmosdb_read_item`
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `account` | string | yes | Cosmos DB account name or endpoint |
| `database` | string | yes | Database name |
| `container` | string | yes | Container name |
| `item_id` | string | yes | Item `id` field value |
| `partition_key` | string | yes | Partition key value |
| `key_env_var` | string | no | Env var holding the account key (default `AZURE_COSMOS_KEY`) |
### `cosmosdb_upsert_item`
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `account` | string | yes | Cosmos DB account name or endpoint |
| `database` | string | yes | Database name |
| `container` | string | yes | Container name |
| `item` | object | yes | Full item document — must include an `id` field |
| `key_env_var` | string | no | Env var holding the account key (default `AZURE_COSMOS_KEY`) |
### `cosmosdb_delete_item`
**Destructive.**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `account` | string | yes | Cosmos DB account name or endpoint |
| `database` | string | yes | Database name |
| `container` | string | yes | Container name |
| `item_id` | string | yes | Item `id` field value |
| `partition_key` | string | yes | Partition key value |
| `key_env_var` | string | no | Env var holding the account key (default `AZURE_COSMOS_KEY`) |
---
## Service Bus Tools
The `namespace` parameter accepts either a short name (e.g. `my-namespace`) or a fully qualified hostname. The `.servicebus.windows.net` suffix is appended automatically if absent.
All Service Bus data-plane tools (everything except `servicebus_list_namespaces`) accept an optional `connection_string_env_var` parameter (default `AZURE_SERVICEBUS_CONNECTION_STRING`). See [Authentication](#authentication).
### `servicebus_list_namespaces`
List all Service Bus namespaces in the current Azure subscription.
### `servicebus_list_queues`
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `namespace` | string | yes | Service Bus namespace |
| `connection_string_env_var` | string | no | Env var holding the connection string (default `AZURE_SERVICEBUS_CONNECTION_STRING`) |
### `servicebus_list_topics`
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `namespace` | string | yes | Service Bus namespace |
| `include_subscriptions` | boolean | no | If true, returns a map of topic → subscription names (default false) |
| `connection_string_env_var` | string | no | Env var holding the connection string (default `AZURE_SERVICEBUS_CONNECTION_STRING`) |
### `servicebus_send_message`
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `namespace` | string | yes | Service Bus namespace |
| `queue` | string | yes | Queue or topic name |
| `body` | string | yes | Message body |
| `session_id` | string | no | Required for session-enabled queues |
| `correlation_id` | string | no | Correlation ID |
| `application_properties` | object | no | Key/value map of custom properties |
| `scheduled_enqueue_time` | string | no | ISO 8601 datetime to enqueue the message |
| `connection_string_env_var` | string | no | Env var holding the connection string (default `AZURE_SERVICEBUS_CONNECTION_STRING`) |
### `servicebus_send_batch`
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `namespace` | string | yes | Service Bus namespace |
| `queue` | string | yes | Queue or topic name |
| `messages` | array | yes | Array of message objects, each with `body` (required), plus optional `session_id`, `correlation_id`, `application_properties`, `scheduled_enqueue_time` |
| `connection_string_env_var` | string | no | Env var holding the connection string (default `AZURE_SERVICEBUS_CONNECTION_STRING`) |
### `servicebus_peek_messages` / `servicebus_peek_messages_to_file`
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `namespace` | string | yes | Service Bus namespace |
| `queue` | string | yes | Queue name |
| `max_count` | integer | no | Max messages (default 10, cap 100) |
| `session_id` | string | no | Peek within a specific session |
| `output_file` | string | yes (to_file only) | Path to write message bodies |
| `connection_string_env_var` | string | no | Env var holding the connection string (default `AZURE_SERVICEBUS_CONNECTION_STRING`) |
### `servicebus_peek_dlq` / `servicebus_peek_dlq_to_file`
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `namespace` | string | yes | Service Bus namespace |
| `queue` | string | yes | Queue name |
| `max_count` | integer | no | Max messages (default 10, cap 100) |
| `output_file` | string | yes (to_file only) | Path to write message bodies |
| `connection_string_env_var` | string | no | Env var holding the connection string (default `AZURE_SERVICEBUS_CONNECTION_STRING`) |
### `servicebus_purge_queue` / `servicebus_purge_dlq`
**Destructive.**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `namespace` | string | yes | Service Bus namespace |
| `queue` | string | yes | Queue name |
| `max_messages` | integer | no | Safety cap (default 1000) |
| `connection_string_env_var` | string | no | Env var holding the connection string (default `AZURE_SERVICEBUS_CONNECTION_STRING`) |
### `servicebus_requeue_dlq`
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `namespace` | string | yes | Service Bus namespace |
| `queue` | string | yes | Queue name |
| `max_messages` | integer | no | Safety cap (default 100) |
| `connection_string_env_var` | string | no | Env var holding the connection string (default `AZURE_SERVICEBUS_CONNECTION_STRING`) |
### `servicebus_peek_subscription_messages` / `servicebus_peek_subscription_messages_to_file`
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `namespace` | string | yes | Service Bus namespace |
| `topic` | string | yes | Topic name |
| `subscription` | string | yes | Subscription name |
| `max_count` | integer | no | Max messages (default 10, cap 100) |
| `session_id` | string | no | Peek within a specific session |
| `output_file` | string | yes (to_file only) | Path to write message bodies |
| `connection_string_env_var` | string | no | Env var holding the connection string (default `AZURE_SERVICEBUS_CONNECTION_STRING`) |
### `servicebus_peek_subscription_dlq` / `servicebus_peek_subscription_dlq_to_file`
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `namespace` | string | yes | Service Bus namespace |
| `topic` | string | yes | Topic name |
| `subscription` | string | yes | Subscription name |
| `max_count` | integer | no | Max messages (default 10, cap 100) |
| `output_file` | string | yes (to_file only) | Path to write message bodies |
| `connection_string_env_var` | string | no | Env var holding the connection string (default `AZURE_SERVICEBUS_CONNECTION_STRING`) |
### `servicebus_purge_subscription` / `servicebus_purge_subscription_dlq`
**Destructive.**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `namespace` | string | yes | Service Bus namespace |
| `topic` | string | yes | Topic name |
| `subscription` | string | yes | Subscription name |
| `max_messages` | integer | no | Safety cap (default 1000) |
| `connection_string_env_var` | string | no | Env var holding the connection string (default `AZURE_SERVICEBUS_CONNECTION_STRING`) |
### `servicebus_requeue_subscription_dlq`
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `namespace` | string | yes | Service Bus namespace |
| `topic` | string | yes | Topic name |
| `subscription` | string | yes | Subscription name |
| `max_messages` | integer | no | Safety cap (default 100) |
| `connection_string_env_var` | string | no | Env var holding the connection string (default `AZURE_SERVICEBUS_CONNECTION_STRING`) |
---
## Authorization / PIM Tools
### `authorization_list_eligible_roles`
List all Azure PIM roles you are eligible to activate, across all accessible subscriptions. Returns role name, scope, and whether the eligibility is permanent or time-limited.
### `authorization_activate_role`
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `role` | string | yes | Role name as returned by `authorization_list_eligible_roles` |
| `scope` | string | yes | Scope as returned by `authorization_list_eligible_roles` |
| `justification` | string | yes | Reason for activation |
| `duration` | string | no | ISO 8601 duration (e.g. `PT4H`). Defaults to the policy maximum. |
Returns activation status and request ID. `Provisioned` means immediately active; `PendingApproval` means an approver must act first.
---
## Security
- Authentication defaults to `DefaultAzureCredential`. When key-based or connection-string auth is used via environment variables, only the env var *name* is passed as a tool argument, never the secret value itself.
- `purge_*` and `requeue_*` tools enforce a `max_messages` safety cap to prevent accidental bulk operations.
- `cosmosdb_delete_item` is a hard point-delete requiring both item ID and partition key.
TDQS
Scored across 31 tools
Tools are clearly disambiguated by service prefix (authorization_, cosmosdb_, servicebus_) and distinct verbs. Even similar operations like peek across different targets (queue, subscription, DLQ) are precisely named, leaving no ambiguity.
All tools follow a consistent pattern: service_verb_noun (e.g., cosmosdb_list_databases, servicebus_send_batch). The naming is uniform across all three services, making it predictable for agents.
31 tools is high but justifiable given coverage of three distinct Azure services. However, the PIM portion only has 2 tools, which feels thin compared to the 11 for Cosmos DB and 18 for Service Bus, indicating slight over-scoping on the latter.
Cosmos DB covers essential operations (list, read, write, query, delete) with container info and count; Service Bus covers listing, peeking (with file variants for large payloads), purging, requeueing, and sending. Missing: ability to consume/receive messages from Service Bus (only peek), but that may be by design to avoid destructive operations. Minor gap but overall solid.