Skip to main content
Glama
BrianDeacon

azure-utils-mcp

by BrianDeacon
README.md
# 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

A3.9/5.0

Scored across 31 tools

Disambiguation5/5

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.

Naming Consistency5/5

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.

Tool Count3/5

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.

Completeness4/5

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.

Maintenance

ActivityInactive
ResponsivenessNo issues