Repository: Azure/azure-mcp (2025-07-15T18:19:07Z)

Issue:
Add azmcp storage datalake file-system list-paths command
Using /src/docs/new-command.md as a guide, implement the following command:

azmcp storage datalake file-system list-paths


Discussion:

Patch:
diff --git a/.vscode/cspell.json b/.vscode/cspell.json
index 126c9d186..68dd6565f 100644
--- a/.vscode/cspell.json
+++ b/.vscode/cspell.json
@@ -182,6 +182,7 @@
         "containerapps",
         "cvzf",
         "dataplane",
+        "datalake",
         "datasource",
         "datasources",
         "Distributedtask",
@@ -247,6 +248,7 @@
         "skillsets",
         "submode",
         "testsettings",
+        "testfilesystem",
         "timespan",
         "toolsets",
         "vectorizable",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 192d8aef4..a762cc182 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,8 @@
 
 - [AOT] Enabled `IlcFoldIdenticalMethodBodies` to fold identical method bodies, saving 3.64 MB in native executable [#598](https://github.com/Azure/azure-mcp/pull/598)
 
+- Support for Azure Data Lake Storage Gen2 operations - List paths in Data Lake file systems via the command: `azmcp storage datalake file-system list-paths`. [#608](https://github.com/Azure/azure-mcp/pull/608)
+
 ### Breaking Changes
 - Support "-" hyphen dash in command names. [[#531](https://github.com/Azure/azure-mcp/pull/531)]
 
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 79602f875..35333ba56 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -26,6 +26,7 @@
     <PackageVersion Include="Azure.Security.KeyVault.Keys" Version="4.7.0" />
     <PackageVersion Include="Azure.Security.KeyVault.Secrets" Version="4.7.0" />
     <PackageVersion Include="Azure.Storage.Blobs" Version="12.24.0" />
+    <PackageVersion Include="Azure.Storage.Files.DataLake" Version="12.22.0" />
     <PackageVersion Include="Azure.ResourceManager.Datadog" Version="1.0.0-beta.5" />
     <PackageVersion Include="Azure.ResourceManager.CosmosDB" Version="1.3.2" />
     <PackageVersion Include="Azure.ResourceManager.OperationalInsights" Version="1.3.0" />
diff --git a/README.md b/README.md
index d9569dc79..83afec76d 100644
--- a/README.md
+++ b/README.md
@@ -81,6 +81,7 @@ The Azure MCP Server supercharges your agents with Azure context. Here are some
 - "List my Azure storage accounts"
 - "Show me the tables in my Storage account"
 - "Get details about my Storage container"
+- "List paths in my Data Lake file system"
 - "Show my key-value pairs in App Config"
 
 ### 🔧 Azure Resource Management
@@ -177,6 +178,7 @@ The Azure MCP Server supercharges your agents with Azure context. Here are some
 - List Storage accounts
 - Manage blob containers and blobs
 - List and query Storage tables
+- List paths in Data Lake file systems
 - Get container properties and metadata
 
 Agents and models can discover and learn best practices and usage guidelines for the `azd` MCP tool. For more information, see [AZD Best Practices](https://github.com/Azure/azure-mcp/tree/main/src/Areas/Extension/Resources/azd-best-practices.txt).
diff --git a/docs/azmcp-commands.md b/docs/azmcp-commands.md
index cf3ca3b8c..ae7ab66ac 100644
--- a/docs/azmcp-commands.md
+++ b/docs/azmcp-commands.md
@@ -589,6 +589,11 @@ azmcp storage blob container list --subscription <subscription> \
 azmcp storage blob container details --subscription <subscription> \
                                      --account-name <account-name> \
                                      --container-name <container-name>
+
+# List paths in a Data Lake file system
+azmcp storage datalake file-system list-paths --subscription <subscription> \
+                                              --account-name <account-name> \
+                                              --file-system-name <file-system-name>
 ```
 
 ### Azure Subscription Management
diff --git a/infra/services/storage.bicep b/infra/services/storage.bicep
index 8eb1cb5c7..db0779bb3 100644
--- a/infra/services/storage.bicep
+++ b/infra/services/storage.bicep
@@ -23,6 +23,7 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = {
   kind: 'StorageV2'
   properties: {
     allowSharedKeyAccess: false
+    isHnsEnabled: true
   }
 
   resource blobServices 'blobServices' = {
@@ -30,6 +31,12 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = {
     resource fooContainer 'containers' = { name: 'foo' }
     resource barContainer 'containers' = { name: 'bar' }
     resource bazContainer 'containers' = { name: 'baz' }
+    resource testFileSystem 'containers' = { 
+      name: 'testfilesystem'
+      properties: {
+        publicAccess: 'None'
+      }
+    }
   }
 
   resource tableServices 'tableServices' = {
diff --git a/src/Areas/Storage/Commands/DataLake/FileSystem/BaseFileSystemCommand.cs b/src/Areas/Storage/Commands/DataLake/FileSystem/BaseFileSystemCommand.cs
new file mode 100644
index 000000000..d5221c444
--- /dev/null
+++ b/src/Areas/Storage/Commands/DataLake/FileSystem/BaseFileSystemCommand.cs
@@ -0,0 +1,30 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System.Diagnostics.CodeAnalysis;
+using AzureMcp.Areas.Storage.Commands;
+using AzureMcp.Areas.Storage.Options;
+using AzureMcp.Areas.Storage.Options.DataLake;
+using AzureMcp.Commands;
+
+namespace AzureMcp.Areas.Storage.Commands.DataLake.FileSystem;
+
+public abstract class BaseFileSystemCommand<
+    [DynamicallyAccessedMembers(TrimAnnotations.CommandAnnotations)] TOptions>
+    : BaseStorageCommand<TOptions> where TOptions : BaseFileSystemOptions, new()
+{
+    protected readonly Option<string> _fileSystemOption = StorageOptionDefinitions.FileSystem;
+
+    protected override void RegisterOptions(Command command)
+    {
+        base.RegisterOptions(command);
+        command.AddOption(_fileSystemOption);
+    }
+
+    protected override TOptions BindOptions(ParseResult parseResult)
+    {
+        var options = base.BindOptions(parseResult);
+        options.FileSystem = parseResult.GetValueForOption(_fileSystemOption);
+        return options;
+    }
+}
diff --git a/src/Areas/Storage/Commands/DataLake/FileSystem/FileSystemListPathsCommand.cs b/src/Areas/Storage/Commands/DataLake/FileSystem/FileSystemListPathsCommand.cs
new file mode 100644
index 000000000..9645bacea
--- /dev/null
+++ b/src/Areas/Storage/Commands/DataLake/FileSystem/FileSystemListPathsCommand.cs
@@ -0,0 +1,65 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using AzureMcp.Areas.Storage.Models;
+using AzureMcp.Areas.Storage.Options.DataLake.FileSystem;
+using AzureMcp.Areas.Storage.Services;
+using AzureMcp.Commands.Storage;
+using AzureMcp.Services.Telemetry;
+using Microsoft.Extensions.Logging;
+
+namespace AzureMcp.Areas.Storage.Commands.DataLake.FileSystem;
+
+public sealed class FileSystemListPathsCommand(ILogger<FileSystemListPathsCommand> logger) : BaseFileSystemCommand<ListPathsOptions>
+{
+    private const string CommandTitle = "List Data Lake File System Paths";
+    private readonly ILogger<FileSystemListPathsCommand> _logger = logger;
+
+    public override string Name => "list-paths";
+
+    public override string Description =>
+        """
+        List all paths in a Data Lake file system. This command retrieves and displays all paths (files and directories)
+        available in the specified Data Lake file system within the storage account. Results include path names, 
+        types (file or directory), and metadata, returned as a JSON array. Requires account-name and file-system-name.
+        """;
+
+    public override string Title => CommandTitle;
+
+    [McpServerTool(Destructive = false, ReadOnly = true, Title = CommandTitle)]
+    public override async Task<CommandResponse> ExecuteAsync(CommandContext context, ParseResult parseResult)
+    {
+        var options = BindOptions(parseResult);
+
+        try
+        {
+            if (!Validate(parseResult.CommandResult, context.Response).IsValid)
+            {
+                return context.Response;
+            }
+
+            context.Activity?.WithSubscriptionTag(options);
+
+            var storageService = context.GetService<IStorageService>();
+            var paths = await storageService.ListDataLakePaths(
+                options.Account!,
+                options.FileSystem!,
+                options.Subscription!,
+                options.Tenant,
+                options.RetryPolicy);
+
+            context.Response.Results = ResponseResult.Create(
+                new FileSystemListPathsCommandResult(paths ?? []),
+                StorageJsonContext.Default.FileSystemListPathsCommandResult);
+        }
+        catch (Exception ex)
+        {
+            _logger.LogError(ex, "Error listing Data Lake file system paths. Account: {Account}, FileSystem: {FileSystem}.", options.Account, options.FileSystem);
+            HandleException(context, ex);
+        }
+
+        return context.Response;
+    }
+
+    internal record FileSystemListPathsCommandResult(List<DataLakePathInfo> Paths);
+}
diff --git a/src/Areas/Storage/Commands/StorageJsonContext.cs b/src/Areas/Storage/Commands/StorageJsonContext.cs
index 9a2d2aa5c..31df77bd4 100644
--- a/src/Areas/Storage/Commands/StorageJsonContext.cs
+++ b/src/Areas/Storage/Commands/StorageJsonContext.cs
@@ -5,6 +5,7 @@
 using AzureMcp.Areas.Storage.Commands.Account;
 using AzureMcp.Areas.Storage.Commands.Blob;
 using AzureMcp.Areas.Storage.Commands.Blob.Container;
+using AzureMcp.Areas.Storage.Commands.DataLake.FileSystem;
 using AzureMcp.Areas.Storage.Commands.Table;
 
 namespace AzureMcp.Commands.Storage;
@@ -14,6 +15,7 @@ namespace AzureMcp.Commands.Storage;
 [JsonSerializable(typeof(TableListCommand.TableListCommandResult))]
 [JsonSerializable(typeof(ContainerListCommand.ContainerListCommandResult))]
 [JsonSerializable(typeof(ContainerDetailsCommand.ContainerDetailsCommandResult))]
+[JsonSerializable(typeof(FileSystemListPathsCommand.FileSystemListPathsCommandResult))]
 [JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
 internal sealed partial class StorageJsonContext : JsonSerializerContext
 {
diff --git a/src/Areas/Storage/Models/DataLakePathInfo.cs b/src/Areas/Storage/Models/DataLakePathInfo.cs
new file mode 100644
index 000000000..35fb4125e
--- /dev/null
+++ b/src/Areas/Storage/Models/DataLakePathInfo.cs
@@ -0,0 +1,13 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System.Text.Json.Serialization;
+
+namespace AzureMcp.Areas.Storage.Models;
+
+public record DataLakePathInfo(
+    [property: JsonPropertyName("name")] string Name,
+    [property: JsonPropertyName("type")] string Type,
+    [property: JsonPropertyName("size")] long? Size,
+    [property: JsonPropertyName("lastModified")] DateTimeOffset? LastModified,
+    [property: JsonPropertyName("etag")] string? ETag);
diff --git a/src/Areas/Storage/Options/DataLake/BaseFileSystemOptions.cs b/src/Areas/Storage/Options/DataLake/BaseFileSystemOptions.cs
new file mode 100644
index 000000000..cea46e4ab
--- /dev/null
+++ b/src/Areas/Storage/Options/DataLake/BaseFileSystemOptions.cs
@@ -0,0 +1,12 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System.Text.Json.Serialization;
+
+namespace AzureMcp.Areas.Storage.Options.DataLake;
+
+public class BaseFileSystemOptions : BaseStorageOptions
+{
+    [JsonPropertyName(StorageOptionDefinitions.FileSystemName)]
+    public string? FileSystem { get; set; }
+}
diff --git a/src/Areas/Storage/Options/DataLake/FileSystem/ListPathsOptions.cs b/src/Areas/Storage/Options/DataLake/FileSystem/ListPathsOptions.cs
new file mode 100644
index 000000000..360ee4330
--- /dev/null
+++ b/src/Areas/Storage/Options/DataLake/FileSystem/ListPathsOptions.cs
@@ -0,0 +1,6 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+namespace AzureMcp.Areas.Storage.Options.DataLake.FileSystem;
+
+public class ListPathsOptions : BaseFileSystemOptions;
diff --git a/src/Areas/Storage/Options/StorageOptionDefinitions.cs b/src/Areas/Storage/Options/StorageOptionDefinitions.cs
index 1fd80e1e8..e52c76cf4 100644
--- a/src/Areas/Storage/Options/StorageOptionDefinitions.cs
+++ b/src/Areas/Storage/Options/StorageOptionDefinitions.cs
@@ -8,6 +8,7 @@ public static class StorageOptionDefinitions
     public const string AccountName = "account-name";
     public const string ContainerName = "container-name";
     public const string TableName = "table-name";
+    public const string FileSystemName = "file-system-name";
 
     public static readonly Option<string> Account = new(
         $"--{AccountName}",
@@ -32,4 +33,12 @@ public static class StorageOptionDefinitions
     {
         IsRequired = true
     };
+
+    public static readonly Option<string> FileSystem = new(
+        $"--{FileSystemName}",
+        "The name of the Data Lake file system to access within the storage account."
+    )
+    {
+        IsRequired = true
+    };
 }
diff --git a/src/Areas/Storage/Services/IStorageService.cs b/src/Areas/Storage/Services/IStorageService.cs
index 9c29373f4..60cc09375 100644
--- a/src/Areas/Storage/Services/IStorageService.cs
+++ b/src/Areas/Storage/Services/IStorageService.cs
@@ -2,6 +2,7 @@
 // Licensed under the MIT License.
 
 using Azure.Storage.Blobs.Models;
+using AzureMcp.Areas.Storage.Models;
 using AzureMcp.Options;
 
 namespace AzureMcp.Areas.Storage.Services;
@@ -24,4 +25,10 @@ Task<BlobContainerProperties> GetContainerDetails(
         string subscriptionId,
         string? tenant = null,
         RetryPolicyOptions? retryPolicy = null);
+    Task<List<DataLakePathInfo>> ListDataLakePaths(
+        string accountName,
+        string fileSystemName,
+        string subscriptionId,
+        string? tenant = null,
+        RetryPolicyOptions? retryPolicy = null);
 }
diff --git a/src/Areas/Storage/Services/StorageService.cs b/src/Areas/Storage/Services/StorageService.cs
index c02b72d01..46ce97d08 100644
--- a/src/Areas/Storage/Services/StorageService.cs
+++ b/src/Areas/Storage/Services/StorageService.cs
@@ -8,6 +8,8 @@
 using Azure.ResourceManager.Storage.Models;
 using Azure.Storage.Blobs;
 using Azure.Storage.Blobs.Models;
+using Azure.Storage.Files.DataLake;
+using AzureMcp.Areas.Storage.Models;
 using AzureMcp.Options;
 using AzureMcp.Services.Azure;
 using AzureMcp.Services.Azure.Subscription;
@@ -277,16 +279,7 @@ protected async Task<TableServiceClient> CreateTableServiceClientWithAuth(
         string? tenant = null,
         RetryPolicyOptions? retryPolicy = null)
     {
-        var options = AddDefaultPolicies(new TableClientOptions());
-
-        if (retryPolicy != null)
-        {
-            options.Retry.Delay = TimeSpan.FromSeconds(retryPolicy.DelaySeconds);
-            options.Retry.MaxDelay = TimeSpan.FromSeconds(retryPolicy.MaxDelaySeconds);
-            options.Retry.MaxRetries = retryPolicy.MaxRetries;
-            options.Retry.Mode = retryPolicy.Mode;
-            options.Retry.NetworkTimeout = TimeSpan.FromSeconds(retryPolicy.NetworkTimeoutSeconds);
-        }
+        var options = ConfigureRetryPolicy(AddDefaultPolicies(new TableClientOptions()), retryPolicy);
 
         switch (authMethod)
         {
@@ -309,16 +302,49 @@ protected async Task<TableServiceClient> CreateTableServiceClientWithAuth(
     private async Task<BlobServiceClient> CreateBlobServiceClient(string accountName, string? tenant = null, RetryPolicyOptions? retryPolicy = null)
     {
         var uri = $"https://{accountName}.blob.core.windows.net";
-        var options = AddDefaultPolicies(new BlobClientOptions());
+        var options = ConfigureRetryPolicy(AddDefaultPolicies(new BlobClientOptions()), retryPolicy);
+        return new BlobServiceClient(new Uri(uri), await GetCredential(tenant), options);
+    }
+
+    private async Task<DataLakeServiceClient> CreateDataLakeServiceClient(string accountName, string? tenant = null, RetryPolicyOptions? retryPolicy = null)
+    {
+        var uri = $"https://{accountName}.dfs.core.windows.net";
+        var options = ConfigureRetryPolicy(AddDefaultPolicies(new DataLakeClientOptions()), retryPolicy);
+        return new DataLakeServiceClient(new Uri(uri), await GetCredential(tenant), options);
+    }
 
-        if (retryPolicy != null)
+    public async Task<List<DataLakePathInfo>> ListDataLakePaths(
+        string accountName,
+        string fileSystemName,
+        string subscriptionId,
+        string? tenant = null,
+        RetryPolicyOptions? retryPolicy = null)
+    {
+        ValidateRequiredParameters(accountName, fileSystemName, subscriptionId);
+
+        var dataLakeServiceClient = await CreateDataLakeServiceClient(accountName, tenant, retryPolicy);
+        var fileSystemClient = dataLakeServiceClient.GetFileSystemClient(fileSystemName);
+        var paths = new List<DataLakePathInfo>();
+
+        try
         {
-            options.Retry.Delay = TimeSpan.FromSeconds(retryPolicy.DelaySeconds);
-            options.Retry.MaxDelay = TimeSpan.FromSeconds(retryPolicy.MaxDelaySeconds);
-            options.Retry.MaxRetries = retryPolicy.MaxRetries;
-            options.Retry.Mode = retryPolicy.Mode;
-            options.Retry.NetworkTimeout = TimeSpan.FromSeconds(retryPolicy.NetworkTimeoutSeconds);
+            await foreach (var pathItem in fileSystemClient.GetPathsAsync())
+            {
+                var pathInfo = new DataLakePathInfo(
+                    pathItem.Name,
+                    pathItem.IsDirectory == true ? "directory" : "file",
+                    pathItem.ContentLength,
+                    pathItem.LastModified,
+                    pathItem.ETag.ToString());
+
+                paths.Add(pathInfo);
+            }
         }
-        return new BlobServiceClient(new Uri(uri), await GetCredential(tenant), options);
+        catch (Exception ex)
+        {
+            throw new Exception($"Error listing Data Lake paths: {ex.Message}", ex);
+        }
+
+        return paths;
     }
 }
diff --git a/src/Areas/Storage/StorageSetup.cs b/src/Areas/Storage/StorageSetup.cs
index 732ed94d8..e36f52fdc 100644
--- a/src/Areas/Storage/StorageSetup.cs
+++ b/src/Areas/Storage/StorageSetup.cs
@@ -4,6 +4,7 @@
 using AzureMcp.Areas.Storage.Commands.Account;
 using AzureMcp.Areas.Storage.Commands.Blob;
 using AzureMcp.Areas.Storage.Commands.Blob.Container;
+using AzureMcp.Areas.Storage.Commands.DataLake.FileSystem;
 using AzureMcp.Areas.Storage.Commands.Table;
 using AzureMcp.Areas.Storage.Services;
 using AzureMcp.Commands;
@@ -39,6 +40,14 @@ public void RegisterCommands(CommandGroup rootGroup, ILoggerFactory loggerFactor
         var blobContainer = new CommandGroup("container", "Storage blob container operations - Commands for managing blob container in your Azure Storage accounts.");
         blobs.AddSubGroup(blobContainer);
 
+        // Create Data Lake subgroup under storage
+        var dataLake = new CommandGroup("datalake", "Data Lake Storage operations - Commands for managing Azure Data Lake Storage Gen2 file systems and paths.");
+        storage.AddSubGroup(dataLake);
+
+        // Create file-system subgroup under datalake
+        var fileSystem = new CommandGroup("file-system", "Data Lake file system operations - Commands for managing file systems and paths in Azure Data Lake Storage Gen2.");
+        dataLake.AddSubGroup(fileSystem);
+
         // Register Storage commands
         storageAccount.AddCommand("list", new AccountListCommand(
             loggerFactory.CreateLogger<AccountListCommand>()));
@@ -51,5 +60,8 @@ public void RegisterCommands(CommandGroup rootGroup, ILoggerFactory loggerFactor
             loggerFactory.CreateLogger<ContainerListCommand>()));
         blobContainer.AddCommand("details", new ContainerDetailsCommand(
             loggerFactory.CreateLogger<ContainerDetailsCommand>()));
+
+        fileSystem.AddCommand("list-paths", new FileSystemListPathsCommand(
+            loggerFactory.CreateLogger<FileSystemListPathsCommand>()));
     }
 }
diff --git a/src/AzureMcp.csproj b/src/AzureMcp.csproj
index 6b79a6c3c..c236bd567 100644
--- a/src/AzureMcp.csproj
+++ b/src/AzureMcp.csproj
@@ -71,6 +71,7 @@
     <PackageReference Include="Azure.Security.KeyVault.Keys" />
     <PackageReference Include="Azure.Security.KeyVault.Secrets" />
     <PackageReference Include="Azure.Storage.Blobs" />
+    <PackageReference Include="Azure.Storage.Files.DataLake" />
     <PackageReference Include="Azure.ResourceManager.CosmosDB" />
     <PackageReference Include="Azure.ResourceManager.Grafana" />
     <PackageReference Include="Azure.ResourceManager.OperationalInsights" />
diff --git a/src/Services/Azure/BaseAzureService.cs b/src/Services/Azure/BaseAzureService.cs
index 98d0df6f1..b19286efa 100644
--- a/src/Services/Azure/BaseAzureService.cs
+++ b/src/Services/Azure/BaseAzureService.cs
@@ -73,6 +73,27 @@ protected static T AddDefaultPolicies<T>(T clientOptions) where T : ClientOption
         return clientOptions;
     }
 
+    /// <summary>
+    /// Configures retry policy options on the provided client options
+    /// </summary>
+    /// <typeparam name="T">Type of client options that inherits from ClientOptions</typeparam>
+    /// <param name="clientOptions">The client options to configure</param>
+    /// <param name="retryPolicy">Optional retry policy configuration</param>
+    /// <returns>The configured client options</returns>
+    protected static T ConfigureRetryPolicy<T>(T clientOptions, RetryPolicyOptions? retryPolicy) where T : ClientOptions
+    {
+        if (retryPolicy != null)
+        {
+            clientOptions.Retry.Delay = TimeSpan.FromSeconds(retryPolicy.DelaySeconds);
+            clientOptions.Retry.MaxDelay = TimeSpan.FromSeconds(retryPolicy.MaxDelaySeconds);
+            clientOptions.Retry.MaxRetries = retryPolicy.MaxRetries;
+            clientOptions.Retry.Mode = retryPolicy.Mode;
+            clientOptions.Retry.NetworkTimeout = TimeSpan.FromSeconds(retryPolicy.NetworkTimeoutSeconds);
+        }
+
+        return clientOptions;
+    }
+
     /// <summary>
     /// Creates an Azure Resource Manager client with optional retry policy
     /// </summary>
@@ -93,17 +114,7 @@ protected async Task<ArmClient> CreateArmClientAsync(string? tenant = null, Retr
         try
         {
             var credential = await GetCredential(tenantId);
-            var options = AddDefaultPolicies(new ArmClientOptions());
-
-            // Configure retry policy if provided
-            if (retryPolicy != null)
-            {
-                options.Retry.MaxRetries = retryPolicy.MaxRetries;
-                options.Retry.Mode = retryPolicy.Mode;
-                options.Retry.Delay = TimeSpan.FromSeconds(retryPolicy.DelaySeconds);
-                options.Retry.MaxDelay = TimeSpan.FromSeconds(retryPolicy.MaxDelaySeconds);
-                options.Retry.NetworkTimeout = TimeSpan.FromSeconds(retryPolicy.NetworkTimeoutSeconds);
-            }
+            var options = ConfigureRetryPolicy(AddDefaultPolicies(new ArmClientOptions()), retryPolicy);
 
             _armClient = new ArmClient(credential, default, options);
             _lastArmClientTenantId = tenantId;


Test patch:
diff --git a/e2eTests/e2eTestPrompts.md b/e2eTests/e2eTestPrompts.md
index c6cbcbc28..66b48c2aa 100644
--- a/e2eTests/e2eTestPrompts.md
+++ b/e2eTests/e2eTestPrompts.md
@@ -238,6 +238,8 @@ This file contains prompts used for end-to-end testing to ensure each tool is in
 | azmcp-storage-blob-list | Show me the blobs in the blob container <container_name> in the storage account <account_name> |
 | azmcp-storage-table-list | List all tables in the storage account <account_name> |
 | azmcp-storage-table-list | Show me the tables in the storage account <account_name> |
+| azmcp-storage-datalake-file-system-list-paths | List all paths in the Data Lake file system <file_system_name> in the storage account <account_name> |
+| azmcp-storage-datalake-file-system-list-paths | Show me the paths in the Data Lake file system <file_system_name> in the storage account <account_name> |
 
 ## Azure Subscription Management
 
diff --git a/tests/Areas/Storage/LiveTests/StorageCommandTests.cs b/tests/Areas/Storage/LiveTests/StorageCommandTests.cs
index ae9de5c6f..87606b19c 100644
--- a/tests/Areas/Storage/LiveTests/StorageCommandTests.cs
+++ b/tests/Areas/Storage/LiveTests/StorageCommandTests.cs
@@ -208,5 +208,22 @@ public async Task Should_get_container_details_with_tenant_authkey()
             var actual = result.AssertProperty("details");
             Assert.Equal(JsonValueKind.Object, actual.ValueKind);
         }
+
+        [Fact]
+        [Trait("Category", "Live")]
+        public async Task Should_list_datalake_filesystem_paths()
+        {
+            var result = await CallToolAsync(
+                "azmcp_storage_datalake_file-system_list-paths",
+                new()
+                {
+                { "subscription", Settings.SubscriptionName },
+                { "account-name", Settings.ResourceBaseName },
+                { "file-system-name", "testfilesystem" }
+                });
+
+            var actual = result.AssertProperty("paths");
+            Assert.Equal(JsonValueKind.Array, actual.ValueKind);
+        }
     }
 }
diff --git a/tests/Areas/Storage/UnitTests/DataLake/FileSystem/FileSystemListPathsCommandTests.cs b/tests/Areas/Storage/UnitTests/DataLake/FileSystem/FileSystemListPathsCommandTests.cs
new file mode 100644
index 000000000..91f39a21a
--- /dev/null
+++ b/tests/Areas/Storage/UnitTests/DataLake/FileSystem/FileSystemListPathsCommandTests.cs
@@ -0,0 +1,164 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System.CommandLine.Parsing;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using AzureMcp.Areas.Storage.Commands.DataLake.FileSystem;
+using AzureMcp.Areas.Storage.Models;
+using AzureMcp.Areas.Storage.Services;
+using AzureMcp.Models.Command;
+using AzureMcp.Options;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using NSubstitute;
+using NSubstitute.ExceptionExtensions;
+using Xunit;
+
+namespace AzureMcp.Tests.Areas.Storage.UnitTests.DataLake.FileSystem;
+
+[Trait("Area", "Storage")]
+public class FileSystemListPathsCommandTests
+{
+    private readonly IServiceProvider _serviceProvider;
+    private readonly IStorageService _storageService;
+    private readonly ILogger<FileSystemListPathsCommand> _logger;
+    private readonly FileSystemListPathsCommand _command;
+    private readonly CommandContext _context;
+    private readonly Parser _parser;
+    private readonly string _knownAccountName = "account123";
+    private readonly string _knownFileSystemName = "filesystem123";
+    private readonly string _knownSubscriptionId = "sub123";
+
+    public FileSystemListPathsCommandTests()
+    {
+        _storageService = Substitute.For<IStorageService>();
+        _logger = Substitute.For<ILogger<FileSystemListPathsCommand>>();
+
+        var collection = new ServiceCollection().AddSingleton(_storageService);
+
+        _serviceProvider = collection.BuildServiceProvider();
+        _command = new(_logger);
+        _context = new(_serviceProvider);
+        _parser = new(_command.GetCommand());
+    }
+
+    [Fact]
+    public async Task ExecuteAsync_WithValidParameters_ReturnsPaths()
+    {
+        // Arrange
+        var expectedPaths = new List<DataLakePathInfo>
+        {
+            new("file1.txt", "file", 1024, DateTimeOffset.Now, "\"etag1\""),
+            new("directory1", "directory", null, DateTimeOffset.Now, "\"etag2\"")
+        };
+
+        _storageService.ListDataLakePaths(Arg.Is(_knownAccountName), Arg.Is(_knownFileSystemName), Arg.Is(_knownSubscriptionId),
+            Arg.Any<string>(), Arg.Any<RetryPolicyOptions>()).Returns(expectedPaths);
+
+        var args = _parser.Parse([
+            "--account-name", _knownAccountName,
+            "--file-system-name", _knownFileSystemName,
+            "--subscription", _knownSubscriptionId
+        ]);
+
+        // Act
+        var response = await _command.ExecuteAsync(_context, args);
+
+        // Assert
+        Assert.NotNull(response);
+        Assert.NotNull(response.Results);
+
+        var json = JsonSerializer.Serialize(response.Results);
+        var result = JsonSerializer.Deserialize<FileSystemListPathsResult>(json);
+
+        Assert.NotNull(result);
+        Assert.Equal(expectedPaths.Count, result.Paths.Count);
+        Assert.Equal(expectedPaths[0].Name, result.Paths[0].Name);
+        Assert.Equal(expectedPaths[0].Type, result.Paths[0].Type);
+    }
+
+    [Fact]
+    public async Task ExecuteAsync_ReturnsEmptyArray_WhenNoPaths()
+    {
+        // Arrange
+        _storageService.ListDataLakePaths(Arg.Is(_knownAccountName), Arg.Is(_knownFileSystemName), Arg.Is(_knownSubscriptionId),
+            Arg.Any<string>(), Arg.Any<RetryPolicyOptions>()).Returns([]);
+
+        var args = _parser.Parse([
+            "--account-name", _knownAccountName,
+            "--file-system-name", _knownFileSystemName,
+            "--subscription", _knownSubscriptionId
+        ]);
+
+        // Act
+        var response = await _command.ExecuteAsync(_context, args);
+
+        // Assert
+        Assert.NotNull(response);
+        Assert.NotNull(response.Results);
+
+        var json = JsonSerializer.Serialize(response.Results);
+        var result = JsonSerializer.Deserialize<FileSystemListPathsResult>(json);
+
+        Assert.NotNull(result);
+        Assert.Empty(result.Paths);
+    }
+
+    [Fact]
+    public async Task ExecuteAsync_HandlesException()
+    {
+        // Arrange
+        var expectedError = "Test error";
+
+        _storageService.ListDataLakePaths(Arg.Is(_knownAccountName), Arg.Is(_knownFileSystemName), Arg.Is(_knownSubscriptionId),
+            null, Arg.Any<RetryPolicyOptions>()).ThrowsAsync(new Exception(expectedError));
+
+        var args = _parser.Parse([
+            "--account-name", _knownAccountName,
+            "--file-system-name", _knownFileSystemName,
+            "--subscription", _knownSubscriptionId
+        ]);
+
+        // Act
+        var response = await _command.ExecuteAsync(_context, args);
+
+        // Assert
+        Assert.NotNull(response);
+        Assert.Equal(500, response.Status);
+        Assert.StartsWith(expectedError, response.Message);
+    }
+
+    [Theory]
+    [InlineData("--file-system-name filesystem123 --subscription sub123", false)] // Missing account
+    [InlineData("--account-name account123 --subscription sub123", false)] // Missing file-system
+    [InlineData("--account-name account123 --file-system-name filesystem123", false)] // Missing subscription
+    [InlineData("--account-name account123 --file-system-name filesystem123 --subscription sub123", true)] // Valid
+    public async Task ExecuteAsync_ValidatesRequiredParameters(string args, bool shouldSucceed)
+    {
+        // Arrange
+        if (shouldSucceed)
+        {
+            _storageService.ListDataLakePaths(Arg.Any<string>(), Arg.Any<string>(), Arg.Any<string>(),
+                Arg.Any<string>(), Arg.Any<RetryPolicyOptions>()).Returns([]);
+        }
+
+        var parseResult = _parser.Parse(args.Split(' '));
+
+        // Act
+        var response = await _command.ExecuteAsync(_context, parseResult);
+
+        // Assert
+        Assert.Equal(shouldSucceed ? 200 : 400, response.Status);
+        if (!shouldSucceed)
+        {
+            Assert.Contains("required", response.Message.ToLower());
+        }
+    }
+
+    private class FileSystemListPathsResult
+    {
+        [JsonPropertyName("paths")]
+        public List<DataLakePathInfo> Paths { get; set; } = [];
+    }
+}