Skip to main content
Glama

Azure MCP Server

Official
MIT License
1,161
  • Linux
  • Apple
AppConfigService.cs10.2 kB
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using Azure.Core; using Azure.Data.AppConfiguration; using Azure.ResourceManager.AppConfiguration; using Azure.ResourceManager.Resources; using AzureMcp.AppConfig.Models; using AzureMcp.Core.Models.Identity; using AzureMcp.Core.Options; using AzureMcp.Core.Services.Azure; using AzureMcp.Core.Services.Azure.Subscription; using AzureMcp.Core.Services.Azure.Tenant; namespace AzureMcp.AppConfig.Services; public class AppConfigService(ISubscriptionService subscriptionService, ITenantService tenantService) : BaseAzureService(tenantService), IAppConfigService { private readonly ISubscriptionService _subscriptionService = subscriptionService ?? throw new ArgumentNullException(nameof(subscriptionService)); public async Task<List<AppConfigurationAccount>> GetAppConfigAccounts(string subscription, string? tenant = null, RetryPolicyOptions? retryPolicy = null) { ValidateRequiredParameters(subscription); var subscriptionResource = await _subscriptionService.GetSubscription(subscription, tenant, retryPolicy); var accounts = new List<AppConfigurationAccount>(); await foreach (var account in subscriptionResource.GetAppConfigurationStoresAsync()) { ResourceIdentifier resourceId = account.Id; if (resourceId.ToString().Length == 0) continue; var acc = new AppConfigurationAccount { Name = account.Data.Name, Location = account.Data.Location.ToString(), Endpoint = account.Data.Endpoint, CreationDate = account.Data.CreatedOn?.DateTime ?? DateTime.MinValue, PublicNetworkAccess = account.Data.PublicNetworkAccess.HasValue && account.Data.PublicNetworkAccess.Value.ToString().Equals("Enabled", StringComparison.OrdinalIgnoreCase), Sku = account.Data.SkuName, Tags = account.Data.Tags ?? new Dictionary<string, string>(), DisableLocalAuth = account.Data.DisableLocalAuth, SoftDeleteRetentionInDays = account.Data.SoftDeleteRetentionInDays, EnablePurgeProtection = account.Data.EnablePurgeProtection, CreateMode = account.Data.CreateMode?.ToString(), // Map the new managed identity structure ManagedIdentity = account.Data.Identity == null ? null : new ManagedIdentityInfo { SystemAssignedIdentity = new SystemAssignedIdentityInfo { Enabled = account.Data.Identity != null, TenantId = account.Data.Identity?.TenantId?.ToString(), PrincipalId = account.Data.Identity?.PrincipalId?.ToString() }, UserAssignedIdentities = account.Data.Identity?.UserAssignedIdentities? .Select(id => new UserAssignedIdentityInfo { ClientId = id.Value.ClientId?.ToString(), PrincipalId = id.Value.PrincipalId?.ToString() }) .ToArray() }, // Full encryption properties from KeyVaultProperties Encryption = account.Data.EncryptionKeyVaultProperties == null ? null : new EncryptionProperties { KeyIdentifier = account.Data.EncryptionKeyVaultProperties.KeyIdentifier, IdentityClientId = account.Data.EncryptionKeyVaultProperties.IdentityClientId, } }; accounts.Add(acc); } return accounts; } public async Task<List<KeyValueSetting>> ListKeyValues( string accountName, string subscription, string? key = null, string? label = null, string? tenant = null, RetryPolicyOptions? retryPolicy = null) { ValidateRequiredParameters(accountName, subscription); var client = await GetConfigurationClient(accountName, subscription, tenant, retryPolicy); var settings = new List<KeyValueSetting>(); var selector = new SettingSelector { KeyFilter = string.IsNullOrEmpty(key) ? null : key, LabelFilter = string.IsNullOrEmpty(label) ? null : label }; await foreach (var setting in client.GetConfigurationSettingsAsync(selector)) { settings.Add(new KeyValueSetting { Key = setting.Key, Value = setting.Value, Label = setting.Label ?? string.Empty, ContentType = setting.ContentType ?? string.Empty, ETag = new ETag { Value = setting.ETag.ToString() }, LastModified = setting.LastModified, Locked = setting.IsReadOnly }); } return settings; } public async Task<KeyValueSetting> GetKeyValue(string accountName, string key, string subscription, string? tenant = null, RetryPolicyOptions? retryPolicy = null, string? label = null, string? contentType = null) { ValidateRequiredParameters(accountName, key, subscription); var client = await GetConfigurationClient(accountName, subscription, tenant, retryPolicy); var response = await client.GetConfigurationSettingAsync(key, label, cancellationToken: default); var setting = response.Value; return new KeyValueSetting { Key = setting.Key, Value = setting.Value, Label = setting.Label ?? string.Empty, ContentType = setting.ContentType ?? string.Empty, ETag = new ETag { Value = setting.ETag.ToString() }, LastModified = setting.LastModified, Locked = setting.IsReadOnly }; } public async Task LockKeyValue(string accountName, string key, string subscription, string? tenant = null, RetryPolicyOptions? retryPolicy = null, string? label = null) { await SetKeyValueReadOnlyState(accountName, key, subscription, tenant, retryPolicy, label, true); } public async Task UnlockKeyValue(string accountName, string key, string subscription, string? tenant = null, RetryPolicyOptions? retryPolicy = null, string? label = null) { await SetKeyValueReadOnlyState(accountName, key, subscription, tenant, retryPolicy, label, false); } public async Task SetKeyValue(string accountName, string key, string value, string subscription, string? tenant = null, RetryPolicyOptions? retryPolicy = null, string? label = null, string? contentType = null, string[]? tags = null) { ValidateRequiredParameters(accountName, key, value, subscription); var client = await GetConfigurationClient(accountName, subscription, tenant, retryPolicy); // Create a ConfigurationSetting object to include contentType if provided var setting = new ConfigurationSetting(key, value, label) { ContentType = contentType }; // Parse and add tags if provided if (tags != null && tags.Length > 0) { foreach (var tagPair in tags) { var parts = tagPair.Split('=', 2); if (parts.Length == 2) { var tagKey = parts[0].Trim(); if (!string.IsNullOrEmpty(tagKey)) { setting.Tags[tagKey] = parts[1]; } } else if (parts.Length == 1 && !string.IsNullOrEmpty(parts[0])) { // Handle tags that don't follow key=value format setting.Tags[parts[0]] = string.Empty; } } } await client.SetConfigurationSettingAsync(setting, cancellationToken: default); } public async Task DeleteKeyValue(string accountName, string key, string subscription, string? tenant = null, RetryPolicyOptions? retryPolicy = null, string? label = null) { ValidateRequiredParameters(accountName, key, subscription); var client = await GetConfigurationClient(accountName, subscription, tenant, retryPolicy); await client.DeleteConfigurationSettingAsync(key, label, cancellationToken: default); } private async Task SetKeyValueReadOnlyState(string accountName, string key, string subscription, string? tenant, RetryPolicyOptions? retryPolicy, string? label, bool isReadOnly) { ValidateRequiredParameters(accountName, key, subscription); var client = await GetConfigurationClient(accountName, subscription, tenant, retryPolicy); await client.SetReadOnlyAsync(key, label, isReadOnly, cancellationToken: default); } private async Task<ConfigurationClient> GetConfigurationClient(string accountName, string subscription, string? tenant, RetryPolicyOptions? retryPolicy) { var subscriptionResource = await _subscriptionService.GetSubscription(subscription, tenant, retryPolicy); var configStore = await FindAppConfigStore(subscriptionResource, accountName, subscription); var endpoint = configStore.Data.Endpoint; var credential = await GetCredential(tenant); AddDefaultPolicies(new ConfigurationClientOptions()); return new ConfigurationClient(new Uri(endpoint), credential); } private static async Task<AppConfigurationStoreResource> FindAppConfigStore(SubscriptionResource subscription, string accountName, string subscriptionIdentifier) { AppConfigurationStoreResource? configStore = null; await foreach (var store in subscription.GetAppConfigurationStoresAsync()) { if (store.Data.Name == accountName) { configStore = store; break; } } if (configStore == null) throw new Exception($"App Configuration store '{accountName}' not found in subscription '{subscriptionIdentifier}'"); return configStore; } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Azure/azure-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server