How the MCP Server Manages Asynchronous Operations and Post-Action Feedback
The MCP server centralizes all OpenStack operation processing through the handle_operation_result function in src/mcp_openstack_ops/mcp_main.py, which automatically detects asynchronous actions via a static configuration map and enriches responses with human-readable status messages, verification commands, and boolean flags indicating whether client-side polling is required.
The call518/mcp-openstack-ops repository implements a Model Context Protocol (MCP) server that standardizes how OpenStack operations are executed and reported back to clients. Understanding how this server handles asynchronous workflows—such as volume attachments or instance resizing—is critical for building reliable client integrations that can properly track operation completion.
Centralized Async Handling in handle_operation_result
Every tool in the MCP server delegates its final response processing to handle_operation_result, defined in src/mcp_openstack_ops/mcp_main.py (lines 94-119). This function serves as the single point of truth for determining whether an operation requires asynchronous monitoring and how to communicate that requirement to the client.
The Async Operations Map
The server maintains a static dictionary called async_operations (lines 55-92) that categorizes which actions are asynchronous based on the operation domain. For example, under "Instance Management" or "Volume Management" keys, the map lists specific async_actions such as attach, detach, or resize.
# src/mcp_openstack_ops/mcp_main.py (simplified excerpt)
async_operations = {
"Instance Management": {
"async_actions": ["resize", "reboot", "migrate"],
"expected_time": "30-60 seconds"
},
"Volume Management": {
"async_actions": ["attach", "detach"],
"expected_time": "10-30 seconds"
}
}
Detecting Asynchronous Actions
When handle_operation_result receives a result dictionary from a tool, it inspects the details['Action'] field and checks whether that action exists in the async_operations map for the given operation_name. If matched, the function triggers the asynchronous enrichment logic.
Enriching Responses with Post-Action Feedback
The MCP server transforms raw OpenStack SDK responses into structured, actionable feedback that clients can consume programmatically or display to end users.
Human-Readable Status Messages
For asynchronous operations, handle_operation_result appends a detailed note to result['message'] (lines 100-107) that includes:
- A clear indication that the operation is asynchronous
- The expected completion time range (e.g., "10-30 seconds")
- A specific verification command the client can execute to check status
# src/mcp_openstack_ops/mcp_main.py (lines 100-107)
if is_async:
result['message'] += (
f"\n\n📋 Note: This is an asynchronous operation. "
f"The command has been initiated successfully "
f"(expected completion: {expected_time}). "
f"You can verify the status using '{verification_command}'."
)
Verification Flags and Operation Types
The function sets two critical metadata fields (lines 108-113) that enable automated client workflows:
result["operation_type"]: Either"asynchronous"or"synchronous"result["verification_needed"]: BooleanTruefor async operations,Falseotherwise
These flags allow client applications to implement polling logic without parsing human-readable text.
Implementation Example: Attaching a Volume
Tools in the MCP server remain agnostic about async handling by delegating to handle_operation_result. Consider the volume attachment tool in src/mcp_openstack_ops/tools/set_server_volume.py:
# src/mcp_openstack_ops/tools/set_server_volume.py
@conditional_tool
@mcp.tool()
async def set_server_volume(
instance_name: str,
volume_name: str,
action: str = "attach",
) -> str:
# Execute OpenStack SDK call
sdk_result = await attach_volume_to_server(instance_name, volume_name)
# Prepare raw result
result = {
"success": True,
"message": f"Volume {volume_name} {action}ed"
}
# Delegate async handling to central processor
return handle_operation_result(
result,
operation_name="Instance Management",
details={
"Action": action,
"Instance": instance_name,
"Volume": volume_name
}
)
The tool focuses purely on executing the OpenStack operation and constructing a basic result. The handle_operation_result function automatically detects that "attach" is an asynchronous action under "Instance Management" and enriches the response accordingly.
Client-Side Integration
When the MCP server returns a response, clients receive a structured JSON payload that clearly indicates whether polling is required:
{
"success": true,
"message": "✅ Volume data-disk attached\n\n📋 Note: This is an asynchronous operation. The attach command has been initiated successfully (expected completion: 10-30 seconds). You can verify the status using 'List all volumes'.",
"operation_type": "asynchronous",
"verification_needed": true
}
Client applications should implement logic that checks verification_needed. When true, the client can extract the verification command from the message or implement custom polling logic using the OpenStack SDK to monitor the resource status until the operation completes.
Summary
-
Centralized Processing: All OpenStack operations route through
handle_operation_resultinsrc/mcp_openstack_ops/mcp_main.py, ensuring consistent async detection and response formatting. -
Static Configuration: The
async_operationsmap (lines 55-92) defines which actions are asynchronous per operation domain, enabling the server to detect async requirements without external API calls. -
Rich Feedback: Asynchronous operations receive enriched messages containing expected completion times and verification commands, plus machine-readable flags (
operation_type,verification_needed) for automated client workflows. -
Tool Agnostic Implementation: Individual tools remain simple by delegating response processing to the central handler, allowing the async logic to be maintained in a single location.
Frequently Asked Questions
How does the MCP server determine if an operation is asynchronous?
The server consults a static dictionary called async_operations defined in src/mcp_openstack_ops/mcp_main.py (lines 55-92). This map lists specific actions—such as attach, detach, or resize—under operation categories like "Instance Management" or "Volume Management". When handle_operation_result processes a response, it checks if the details['Action'] value exists in the corresponding async list for that operation domain.
What fields are added to the response for asynchronous operations?
For asynchronous operations, the server adds or modifies three key fields in the result dictionary: operation_type is set to "asynchronous", verification_needed is set to True, and the message field is appended with a human-readable note containing the expected completion time and a recommended verification command. Synchronous operations receive operation_type: "synchronous" and verification_needed: False.
Where is the async operation configuration defined?
The configuration mapping which actions are asynchronous is defined in src/mcp_openstack_ops/mcp_main.py between lines 55 and 92. This async_operations dictionary uses operation domains as keys (e.g., "Instance Management", "Volume Management") and contains nested dictionaries specifying async_actions (lists of action strings) and expected_time (human-readable duration strings).
How should clients handle the verification_needed flag?
Clients should treat the verification_needed boolean as a signal to implement polling logic. When this flag is True, the client should parse the message field to extract the suggested verification command, or use the operation details to construct an appropriate status query using the OpenStack SDK. The client should then poll the resource status periodically until the operation completes or fails, rather than assuming immediate completion when success is True.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →