About
Zsvirt — Model Context Protocol server
README
ZSvirt MCP Server
English | 简体中文
An MCP server that enables AI assistants to dynamically discover and invoke more than 2,000 ZSvirt APIs.
Features
- API search: Search ZStack APIs by keyword with fuzzy matching
- API description: Retrieve detailed parameter documentation for an API
- API execution: Invoke a ZStack API and return its result
- Metric search: Search available monitoring metrics
- Metric data retrieval: Retrieve monitoring data for a specified metric
Installation
# Install from PyPI
pip install zsvirt-mcp-server
# Or install with uv
uv pip install zsvirt-mcp-server
💡 You can also run the server directly with
uvxorpipx runwithout installing it. See Usage.
Configuration
Set the following environment variables:
export ZSTACK_API_URL="http://localhost:8080" # ZStack API endpoint
export ZSTACK_ALLOW_ALL_API="false" # Allow write operations (optional; default: false)
# Authentication method 1: account and password (automatically logs in and obtains a session)
export ZSTACK_ACCOUNT="admin" # Account name
export ZSTACK_PASSWORD="your-password" # Plain-text password
# Authentication method 2: use an existing session ID
# This method takes precedence over account/password authentication.
export ZSTACK_SESSION_ID="your-session-uuid" # Existing session UUID
# Query response controls (optional)
export ZSTACK_QUERY_DEFAULT_LIMIT="50" # Default Query API limit; set to 0 to disable
export ZSTACK_RESPONSE_SIZE_LIMIT="65536" # Maximum response size in bytes; set to 0 to disable
Authentication methods
| Method | Environment variables | Description |
|---|---|---|
| Account and password | ZSTACK_ACCOUNT + ZSTACK_PASSWORD |
Automatically logs in and obtains a session |
| Session ID | ZSTACK_SESSION_ID |
Uses an existing session and takes precedence over account/password authentication |
💡 If both
ZSTACK_SESSION_IDand account/password credentials are configured, the session ID takes precedence.
Security
By default, only read-only APIs are allowed, including:
Query*— query operationsGet*— get operationsList*— list operationsDescribe*— describe operationsCheck*— check operationsCount*— count operations- Other read-only operations
To enable write APIs such as CreateVmInstance and DeleteVolume, set:
export ZSTACK_ALLOW_ALL_API="true"
⚠️ Warning: When write operations are enabled, an AI assistant can create, delete, and modify resources. Enable this option with care.
Query response controls
The server injects limit=50 into Query APIs by default to prevent a single request from filling the model context window. If a response exceeds 64 KiB, the server truncates the inventories list while preserving valid JSON.
| Environment variable | Default | Description |
|---|---|---|
ZSTACK_QUERY_DEFAULT_LIMIT |
50 |
Default limit injected when a Query API does not specify one; set to 0 to disable |
ZSTACK_RESPONSE_SIZE_LIMIT |
65536 |
Maximum response size in bytes; oversized responses are truncated; set to 0 to disable |
- An explicitly supplied
limitis never overwritten. - A truncated response includes a
_truncationfield suggesting pagination withlimit/startor response reduction withfields.
Usage
Run as an MCP server
# Run directly with uvx (no installation required)
uvx zsvirt-mcp-server
# Or use pipx
pipx run zsvirt-mcp-server
# Run the installed command
zsvirt-mcp-server
SSE transport
The default transport is stdio. Use command-line options or environment variables to enable SSE:
# Command-line options
uvx zsvirt-mcp-server --transport sse --host 0.0.0.0 --port 8000
# Environment variables
export MCP_TRANSPORT="sse"
export MCP_HOST="0.0.0.0"
export MCP_PORT="8000"
export MCP_PATH="/sse" # Optional
uvx zsvirt-mcp-server
The server also supports the native FastMCP variables
FASTMCP_HOST,FASTMCP_PORT, andFASTMCP_MOUNT_PATH.
Streamable HTTP transport
# Command-line options
uvx zsvirt-mcp-server --transport streamable-http --host 0.0.0.0 --port 8000 --streamable-path /mcp
# Environment variables
export MCP_TRANSPORT="streamable-http"
export MCP_HOST="0.0.0.0"
export MCP_PORT="8000"
export MCP_STREAMABLE_PATH="/mcp" # Optional
uvx zsvirt-mcp-server
The server also supports
FASTMCP_STREAMABLE_HTTP_PATH.
HTTP header authentication (multi-tenant mode)
In SSE or Streamable HTTP mode, an administrator can run a shared MCP server while each user supplies their own credentials through HTTP headers.
| HTTP header | Environment variable | Description |
|---|---|---|
X-ZStack-Account |
ZSTACK_ACCOUNT |
Account name |
X-ZStack-Password |
ZSTACK_PASSWORD |
Password |
X-ZStack-Session-Id |
ZSTACK_SESSION_ID |
Existing session; takes precedence over account/password authentication |
X-ZStack-API-URL |
ZSTACK_API_URL |
ZStack management node endpoint; allows proxying multiple environments |
Credential precedence: HTTP headers > environment variables.
# Start a shared MCP server
ZSTACK_ALLOW_ALL_API=false uvx zsvirt-mcp-server --transport streamable-http --host 0.0.0.0 --port 8000
Users can configure credentials as HTTP headers in an MCP client:
{
"mcpServers": {
"zstack": {
"transport": "streamable-http",
"url": "http://mcp-server:8000/mcp",
"headers": {
"X-ZStack-Account": "user-a",
"X-ZStack-Password": "password-a",
"X-ZStack-API-URL": "http://zstack-env-1:8080"
}
}
}
}
- Sessions are cached and reused for the same account.
- Requests with different
X-ZStack-API-URLvalues are routed to different ZStack environments. - stdio mode has no HTTP headers and automatically falls back to environment-variable authentication.
Claude Desktop configuration
Add the server to claude_desktop_config.json.
Method 1: account and password
{
"mcpServers": {
"zstack": {
"command": "uvx",
"args": ["zsvirt-mcp-server"],
"env": {
"ZSTACK_API_URL": "http://your-zstack-server:8080",
"ZSTACK_ACCOUNT": "admin",
"ZSTACK_PASSWORD": "your-password",
"ZSTACK_ALLOW_ALL_API": "false"
}
}
}
}
Method 2: session ID
{
"mcpServers": {
"zstack": {
"command": "uvx",
"args": ["zsvirt-mcp-server"],
"env": {
"ZSTACK_API_URL": "http://your-zstack-server:8080",
"ZSTACK_SESSION_ID": "your-session-uuid",
"ZSTACK_ALLOW_ALL_API": "false"
}
}
}
}
💡 Set
ZSTACK_ALLOW_ALL_APIto"true"to enable create, delete, and modify operations.
Available tools
1. search_api
Search ZStack APIs by keyword.
Parameters:
keywords(list[str]): Search keywords, for example["Query", "Vm"]category(str, optional): Filter by categorylimit(int, default:15): Maximum number of results
2. describe_api
Retrieve detailed parameter documentation for an API.
Parameters:
api_name(str): API name, for exampleQueryVmInstance
3. execute_api
Invoke a ZStack API.
Parameters:
api_name(str): API nameparameters(dict): API parameters
4. search_metric
Search available monitoring metrics.
Parameters:
keywords(list[str]): Search keywordsnamespace(str, optional): Fuzzy namespace filter, such asvmorhostlimit(int, default:20): Maximum number of resultsmatch_mode(str, default:or): Keyword matching mode:andororprefer_namespaces(list[str], optional): Namespaces to rank first; defaults to["ZStack/VM", "ZStack/Host"]
💡 If the namespace is unknown, omit it first. Search results include namespace values that can be used in a subsequent request.
The default
match_modeisor. Passandexplicitly to require all keywords.Metric names can overlap across namespaces. Specify
namespaceorprefer_namespacesto control result ranking.
5. get_metric_data
Retrieve monitoring data.
Parameters:
namespace(str): Namespacemetric_name(str): Metric namestart_time(str | int, optional): Start time as ISO text or a Unix timestamp in secondsend_time(str | int, optional): End time as ISO text or a Unix timestamp in secondsperiod(int, default:60): Sampling period in secondslabels(list[str] | dict, optional): Label filters such as["VMUuid=xxx"]or{"VMUuid": "xxx"}summary_only(bool, optional): Return only statistics: count, maximum, minimum, average, variance, and standard deviation
Response size guidance:
estimated_points = ceil((end_time - start_time) / period) * series_count
series_count is the number of unique label combinations. Omitting labels can return multiple series. Reduce output size by shortening the time range, increasing period, or adding label filters.
6. get_metric_summary
Retrieve aggregated Top-N metric results grouped by a label key.
Parameters:
namespace(str): Namespacemetric_name(str): Metric namelabel_key(str): Grouping label, such asVMUuidorHostUuidmetric_names(list[str], optional): Metrics to combine, such as inbound and outbound metricsstart_time(str | int, optional): Start time as ISO text or a Unix timestamp in secondsend_time(str | int, optional): End time as ISO text or a Unix timestamp in secondsperiod(int, default:60): Sampling period in secondsaggregate(str, default:max): Per-metric aggregation:max,avg,sum, ormincombine(str, default:sum): Multi-metric combination:sum,avg,max, orminthreshold_op(str, optional): Comparison operator:>,>=,<,<=,==, or!=threshold_value(number, optional): Threshold valuetop_n(int, default:10): Number of resultsresolve_resource(str, optional):vmorhost, used to resolve resource names
Query API condition syntax
For Query APIs, the conditions parameter supports these operators:
| Operator | Meaning | Example |
|---|---|---|
= |
Equal | name=test |
!= |
Not equal | state!=Deleted |
> |
Greater than | cpuNum>4 |
>= |
Greater than or equal | memorySize>=1073741824 |
< |
Less than | createDate<2024-01-01 |
<= |
Less than or equal | |
?= |
Fuzzy match (LIKE; some versions use like) |
name?=%test% |
!?= |
Fuzzy non-match | |
~= |
Regular-expression match | name~=.*test.* |
!~= |
Regular-expression non-match | |
=null |
Is null | description=null |
!=null |
Is not null | |
in |
In list | state?=Running,Stopped |
not in |
Not in list | state!?=Deleted,Destroyed |
conditions format:
{
"conditions": [
{"name": "uuid", "op": "=", "value": "xxx"},
{"name": "state", "op": "in", "value": "Running,Stopped"}
]
}
Example interaction
User: "Show me the details of the VM whose UUID starts with ae6e57a0."
The AI assistant will:
- Call
search_api(keywords=["Query", "Vm", "Instance"]) - Call
describe_api(api_name="QueryVmInstance") - Call
execute_api(api_name="QueryVmInstance", parameters={"conditions": [{"name": "uuid", "op": "?=", "value": "ae6e57a0%"}]})
Development
# Clone the repository
git clone https://github.com/ZSvirt/zsvirt-mcp-server.git
cd zsvirt-mcp-server
# Install development dependencies
pip install -e ".[dev]"
# Run tests
pytest
License
MIT
Installing Zsvirt
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/ZSvirt/zsvirt-mcp-serverFAQ
Is Zsvirt MCP free?
Yes, Zsvirt MCP is free — one-click install via Unyly at no cost.
Does Zsvirt need an API key?
No, Zsvirt runs without API keys or environment variables.
Is Zsvirt hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Zsvirt in Claude Desktop, Claude Code or Cursor?
Open Zsvirt on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
GitHub
PRs, issues, code search, CI status
by GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
by mcpdotdirectAmap Maps Mcp Server
MCP server for using the AMap Maps API
by duxiaohuiSupabase
Database, auth and storage
by SupabaseEverything
Reference / test server with prompts, resources, and tools.
Git
Tools to read, search, and manipulate Git repositories.
Sequential Thinking
Dynamic and reflective problem-solving through thought sequences.
Time
Time and timezone conversion capabilities.
Compare Zsvirt with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All development MCPs
