Summary
Using an MCP server that integrates with FlashBlade allows you to query system data and even take direct actions, unlocking a new frontier in agentic storage management.
Managing on-premises storage has traditionally been a tedious, manual process—querying system metrics, monitoring performance, and executing actions often require complex scripts or specialized tools. But what if you could simply ask for the information you need in plain English and get immediate, actionable insights?
That’s where the Model Context Protocol (MCP) comes in. MCP is an open protocol that enables large language models (LLMs) to interact intelligently with applications, bringing natural language capabilities to storage management. In this blog, we’ll show you how to build an MCP server that integrates with Pure Storage® FlashBlade®, allowing you to query system data and even take direct actions—all through an intuitive, AI-powered interface.
By modularizing our approach, we’re unlocking a new frontier in agentic storage management, where automation is not just efficient but also conversational and adaptive. Let’s dive in.
Our target for these actions is a Pure Storage array, specifically a FlashBlade system, but the principals are also applicable to FlashArray™ systems. Using the Claude desktop app, our queries will use the tools provided by the MCP server to interact with the designated Pure Storage array as per this screenshot:
Creating an MCP Server
The first step is to install the uv Python package manager. For installation instructions, refer to the official guide.
Next, we need to create the MCP server structure. For this, we’ll make use of the provided tools within the uv package:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
% uvx create–mcp–server Creating a new MCP server project using uv. This will set up a Python project with MCP dependency. Let‘s begin! Project name (required): pure–mcp–server Project description [A MCP server project]: A MCP server to retrieve realtime information from a Pure Storage FlashBlade Project version [0.1.0]: Project will be created at: /Users/jthomas/mcp/pure–mcp–server Is this correct? [Y/n]: Y .... Claude.app detected. Would you like to install the server into Claude.app now? [Y/n]: Y ✅ Added pure–mcp–server to Claude.app configuration Settings file location: /Users/jthomas/Library/Application Support/Claude/claude_desktop_config.json ✅ Created project pure–mcp–server in pure–mcp–server ℹ️ To install dependencies run: cd pure–mcp–server uv sync —dev —all–extras |
Proceed with the final indicated steps to install the dependencies, and our skeleton MCP server is ready. The source code that we need to modify is located under pure-mcp-server/src/pure-mcp-server. At this point, the code is for a template add-notes tool. We’ll modify that so as to interact with an on-premises Pure Storage FlashBlade array.
From the project folder, we enter into the Python virtual environment that was automatically created by uv, and install the Pure Storage Python SDK, as we will leverage this to interact with the FlashBlade REST API.
1 2 |
% source .venv/bin/activate (pure–mcp–server) % uv pip install py–pure–client |
Then, we add the relevant code to create two MCP tools to run queries against a given FlashBlade array’s endpoints:
- get_arrays
- get_arrays and get_arrays_performance
The MCP server was added automatically to Claude desktop during the initialisation phase. To verify, open the following file and check the entry is correct:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
cat /Users/jthomas/Library/Application\ Support/Claude/claude_desktop_config.json { “mcpServers”: { “pure-mcp-server”: { “command”: “uv”, “args”: [ “–directory”, “/path/to/folder/pure-mcp-server”, “run”, “pure-mcp-server” ] } } } |
In addition to the MCP inspector, we used the following script to validate:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import asyncio from mcp.client.session import ClientSession from mcp.client.stdio import StdioServerParameters, stdio_client async def main(): async with stdio_client( StdioServerParameters(command=“uv”, args=[“–directory”, “/Users/jthomas/mcp/pure-mcp-server”, “run”, “pure-mcp-server”]) ) as (read, write): async with ClientSession(read, write) as session: await session.initialize() # List available tools tools = await session.list_tools() print(tools) # Call the fetch tool result = await session.call_tool(“get-array”, {“host”: “1.2.3.4”, “api_token”: “T-da03****1a98”}) print(result) asyncio.run(main()) |
This code correctly lists my MCP server tools. It also connects to the remote array, performs the necessary API call, and returns the relevant JSON string.
Now, via the Claude desktop app, we can run queries using the MCP server tools against a given Pure Storage FlashBlade:
And with the get-array-full tool, ask about storage space:
Note that this is a pretty idle lab array, but follow-up questions can be asked, such as:
“Create a graph to show the last 7 days’ performance based on the per metric epoch time value. Convert epoch and group performance results per day.”
Running a Modular MCP Tool
The code so far provides basic integration for hardcoded calls per MCP server tool definition, but we may want to submit actions as well as retrieve information. Having one MCP tool per request is not a desirable approach—we must change from a hardcoded REST API call like get_arrays to a modular approach where it accepts any endpoint call as a parameter via a single pure-fb tool to use for any endpoint.
The full code can be found in this GitHub repository.
Usage
With our new MCP server in place, we can run informational queries, such as:
“Use pure-fb on host: 1.2.3.4 with api-token: T-7c7a*****f23e to run the command: get_file_systems and then the command: get_buckets. Sort the items per used size and indicate for each if it is a bucket by tagging the item as ‘s3’ or a file system by tagging the item as ‘fs.’ Make sure to correctly sort by descending order based on used size and list the top 5 by used space.”
This results in the following output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
I‘ll help you retrieve and analyze the file systems and buckets information from your FlashBlade. View result from pure–fb from pureflashblade (local){} View result from pure–fb from pureflashblade (local){} Here are the top 5 storage items (combining both file systems and buckets) sorted by used space in descending order: lbo–outscale–perfs [fs]: 7,240,575,042,227 bytes (7.24 TB) lbo–vertica [fs]: 3,311,892,804,361 bytes (3.31 TB) dm [fs]: 2,213,617,471,583 bytes (2.21 TB) lbo–hdf5 [fs]: 1,643,315,388,928 bytes (1.64 TB) eg–px–share01 [fs]: 869,598,847,641 bytes (869.6 GB) As we can see, the top 5 spots are all occupied by file systems, with the largest being lbo–outscale–perfs at 7.24 TB. For reference, the largest bucket (cvlt–uklab–object–lock at 265.1 GB) would rank much lower in this combined list. |
With this modular approach, we can query any endpoint (get arrays, buckets, file systems, etc.) to retrieve information and take actions on the array. For example, we will run a simple create bucket command using the following query:
“Use pure-fb on host: 1.2.3.4 with api-token: T-7c7a*****f23e and the command post_buckets with the parameters: names=[“jbtmcptest”], bucket=BucketPost(account=Reference(name=’jbt’)) ”
On the Pure Storage FlashBlade array, we can see that the relevant bucket is now present:
And with this query, we create a file system. Note that in this example, we do not give the specific endpoint. We leave this to the LLM to figure out:
“Create a file system using the following parameters: names=[“jbt-myfs”], file_system=FileSystemPost(provisioned=5000, hard_limit_enabled=True, nfs=Nfs(v4_1_enabled=True), smb=Smb(enabled=True), multi_protocol=MultiProtocolPost(access_control_style=”nfs”))”
We can see that ClaudeAI was able to provide the correct command post_file_system to run this request.
Setting the Prompt to Act as an Agent
We will now add some context to the chat and define the behaviour and capabilities of a storage agent that has two arrays to control:
“You are a smart storage management agent that via the pure-fb tool can manage the following two arrays:
array01 at host: 1.2.3.4 with api-token: T-7c7a*****f23e
array02 at host: 1.2.3.5 with api-token: T-f2e0*****3b8d”
With this storage agent defined, we can run queries against both arrays, such as:
“Get all buckets from both arrays, extract name, raw total_used space, and source array into a single list. Sort strictly based on the raw total_used values without any conversions. Provide the top 15 from the list and convert used space to appropriate units for display.”
Our agent starts by gathering the relevant data using get_buckets and get_file_systems against the two arrays:
The agent proceeds to sort the buckets by used space as requested. Note that it took several attempts to get the prompt for the sorting to be correct.
From CLI-driven to AI-assisted Storage Management
With an MCP server, we’ve transformed on-premises storage management from a rigid, command-line-driven process into an AI-assisted, natural language experience. By bridging LLMs with enterprise storage, we’re no longer just retrieving data—we’re commanding our infrastructure dynamically, reducing complexity and opening the door to smarter, more efficient workflows.
But this is just the beginning. Agentic automation is reshaping enterprise technology, and storage is no exception. As these capabilities evolve, we’re moving toward a future where AI-driven storage management is not just a convenience but a competitive advantage. The question isn’t if this will become the new standard—it’s how soon.
Are you ready to take the next step?
![flash array test drive](https://blog.purestorage.com/wp-content/uploads/2024/09/flashallay-test-drive.png)
Pure Storage Virtual Lab
Sign up to experience the future of data storage with Pure Storage FlashArray™.
Free Test Drive
Explore FlashBlade in our virtual lab.