alibaba-cloud-ops-mcp-server 0.8.9__tar.gz → 0.9.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/PKG-INFO +3 -1
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/README.md +2 -0
- alibaba_cloud_ops_mcp_server-0.9.0/README_mcp_args.md +22 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/README_zh.md +2 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/pyproject.toml +2 -2
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/src/alibaba_cloud_ops_mcp_server/alibabacloud/api_meta_client.py +10 -2
- alibaba_cloud_ops_mcp_server-0.9.0/src/alibaba_cloud_ops_mcp_server/alibabacloud/static/PROMPT_UNDERSTANDING.md +134 -0
- alibaba_cloud_ops_mcp_server-0.9.0/src/alibaba_cloud_ops_mcp_server/alibabacloud/static/__init__.py +8 -0
- alibaba_cloud_ops_mcp_server-0.9.0/src/alibaba_cloud_ops_mcp_server/server.py +78 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/src/alibaba_cloud_ops_mcp_server/tools/api_tools.py +27 -1
- alibaba_cloud_ops_mcp_server-0.9.0/src/alibaba_cloud_ops_mcp_server/tools/common_api_tools.py +74 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/tests/alibabacloud/test_api_meta_client.py +29 -7
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/tests/test_server.py +5 -3
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/tests/tools/test_api_tools.py +65 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/uv.lock +66 -65
- alibaba_cloud_ops_mcp_server-0.8.9/src/alibaba_cloud_ops_mcp_server/server.py +0 -51
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/.github/workflows/python-ci.yml +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/.gitignore +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/LICENSE +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/examples/openapi_mcp_quickstart/server.py +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/image/Alibaba-Cloud-Ops-MCP-User-Group-en.png +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/image/Alibaba-Cloud-Ops-MCP-User-Group-zh.png +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/image/alibaba-cloud.png +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/src/__init__.py +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/src/alibaba_cloud_ops_mcp_server/__init__.py +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/src/alibaba_cloud_ops_mcp_server/alibabacloud/__init__.py +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/src/alibaba_cloud_ops_mcp_server/alibabacloud/exception.py +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/src/alibaba_cloud_ops_mcp_server/alibabacloud/utils.py +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/src/alibaba_cloud_ops_mcp_server/config.py +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/src/alibaba_cloud_ops_mcp_server/tools/__init__.py +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/src/alibaba_cloud_ops_mcp_server/tools/cms_tools.py +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/src/alibaba_cloud_ops_mcp_server/tools/oos_tools.py +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/src/alibaba_cloud_ops_mcp_server/tools/oss_tools.py +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/tests/alibabacloud/test_exception.py +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/tests/alibabacloud/test_utils.py +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/tests/test_init.py +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/tests/tools/test_cms_tools.py +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/tests/tools/test_oos_tools.py +0 -0
- {alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/tests/tools/test_oss_tools.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: alibaba-cloud-ops-mcp-server
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
4
4
|
Summary: A MCP server for Alibaba Cloud
|
|
5
5
|
Author-email: Zheng Dayu <dayu.zdy@alibaba-inc.com>
|
|
6
6
|
License-File: LICENSE
|
|
@@ -55,6 +55,8 @@ To use `alibaba-cloud-ops-mcp-server` MCP Server with any other MCP Client, you
|
|
|
55
55
|
}
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
+
[For detailed parameter description, see MCP startup parameter document](./README_mcp_args.md)
|
|
59
|
+
|
|
58
60
|
## MCP Maketplace Integration
|
|
59
61
|
|
|
60
62
|
* [Cline](https://cline.bot/mcp-marketplace)
|
|
@@ -39,6 +39,8 @@ To use `alibaba-cloud-ops-mcp-server` MCP Server with any other MCP Client, you
|
|
|
39
39
|
}
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
+
[For detailed parameter description, see MCP startup parameter document](./README_mcp_args.md)
|
|
43
|
+
|
|
42
44
|
## MCP Maketplace Integration
|
|
43
45
|
|
|
44
46
|
* [Cline](https://cline.bot/mcp-marketplace)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# MCP Startup Parameters Guide
|
|
2
|
+
|
|
3
|
+
This document provides a detailed introduction to the available parameters for starting the Alibaba Cloud MCP Server, helping users configure the server according to their needs.
|
|
4
|
+
|
|
5
|
+
## Parameter Table
|
|
6
|
+
|
|
7
|
+
| Parameter | Required | Type | Default | Description |
|
|
8
|
+
|:--------------:|:--------:|:------:|:----------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
9
|
+
| `--transport` | No | string | `stdio` | Transport protocol for MCP Server communication.<br>Options:<br> • `stdio` <br> • `sse` <br> • `streamable-http` |
|
|
10
|
+
| `--port` | No | int | `8000` | Specifies the port number MCP Server listens on. Make sure the port is not occupied. |
|
|
11
|
+
| `--host` | No | string | `127.0.0.1`| Specifies the host address MCP Server listens on. `0.0.0.0` means listening on all network interfaces. |
|
|
12
|
+
| `--services` | No | string | None | Comma-separated services, e.g., `ecs,vpc`.<br>Supported services:<br> • `ecs`<br> • `oos`<br> • `rds`<br> • `vpc`<br> • `slb`<br> • `ess`<br> • `ros`<br> • `cbn`<br> • `dds`<br> • `r-kvstore` |
|
|
13
|
+
|
|
14
|
+
## Usage Example
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
uv run src/alibaba_cloud_ops_mcp_server/server.py --transport sse --port 8080 --host 0.0.0.0 --services ecs,vpc
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
For more help, please refer to the main project documentation or contact the maintainer.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "alibaba-cloud-ops-mcp-server"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.9.0"
|
|
4
4
|
description = "A MCP server for Alibaba Cloud"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [
|
|
@@ -34,4 +34,4 @@ dev = [
|
|
|
34
34
|
]
|
|
35
35
|
|
|
36
36
|
[project.scripts]
|
|
37
|
-
alibaba-cloud-ops-mcp-server = "alibaba_cloud_ops_mcp_server:main"
|
|
37
|
+
alibaba-cloud-ops-mcp-server = "alibaba_cloud_ops_mcp_server:main"
|
|
@@ -47,9 +47,16 @@ class ApiMetaClient:
|
|
|
47
47
|
@classmethod
|
|
48
48
|
def get_service_version(cls, service):
|
|
49
49
|
data = cls.get_response_from_pop_api(cls.GET_PRODUCT_LIST)
|
|
50
|
-
version = next((item.get(DEFAULT_VERSION) for item in data if item.get(CODE).lower() == service), None)
|
|
50
|
+
version = next((item.get(DEFAULT_VERSION) for item in data if item.get(CODE).lower() == service.lower()), None)
|
|
51
51
|
return version
|
|
52
52
|
|
|
53
|
+
@classmethod
|
|
54
|
+
def get_all_service_info(cls):
|
|
55
|
+
data = cls.get_response_from_pop_api(cls.GET_PRODUCT_LIST)
|
|
56
|
+
filtered_data = [{"code": item["code"], "name": item["name"]} for item in data]
|
|
57
|
+
|
|
58
|
+
return filtered_data
|
|
59
|
+
|
|
53
60
|
@classmethod
|
|
54
61
|
def get_service_style(cls, service):
|
|
55
62
|
data = cls.get_response_from_pop_api(cls.GET_PRODUCT_LIST)
|
|
@@ -147,7 +154,8 @@ class ApiMetaClient:
|
|
|
147
154
|
return combined_params
|
|
148
155
|
|
|
149
156
|
@classmethod
|
|
150
|
-
def get_apis_in_service(cls, service
|
|
157
|
+
def get_apis_in_service(cls, service):
|
|
158
|
+
version = cls.get_service_version(service)
|
|
151
159
|
data = cls.get_response_from_pop_api(cls.GET_API_OVERVIEW, service=service, version=version)
|
|
152
160
|
apis = list(data[APIS].keys())
|
|
153
161
|
return apis
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
## Optimized Prompt
|
|
2
|
+
|
|
3
|
+
When a user submits a request, analyze their needs and check if matching tools exist. If yes, use them directly. If not, proceed to the retrieval phase.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Request Flow
|
|
8
|
+
|
|
9
|
+
1. **Analysis & Selection**
|
|
10
|
+
- Analyze user intent
|
|
11
|
+
- Choose between specific tools or common API flow
|
|
12
|
+
- Verify service support
|
|
13
|
+
|
|
14
|
+
2. **API Flow** (if no specific tool)
|
|
15
|
+
- Identify service
|
|
16
|
+
- Select API via `ListAPIs`
|
|
17
|
+
- Get params via `GetAPIInfo`
|
|
18
|
+
- Execute via `CommonAPICaller`
|
|
19
|
+
|
|
20
|
+
3. **Error Handling**
|
|
21
|
+
- Service not supported: "Unfortunately, we currently do not support this service"
|
|
22
|
+
- API failures: Check error code, params, permissions
|
|
23
|
+
- Param validation: Verify types and formats
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
### Retrieval Phase
|
|
28
|
+
|
|
29
|
+
1. **Service Selection**
|
|
30
|
+
|
|
31
|
+
Supported Services:
|
|
32
|
+
- ecs: Elastic Compute Service (ECS)
|
|
33
|
+
- oos: Operations Orchestration Service (OOS)
|
|
34
|
+
- rds: Relational Database Service (RDS)
|
|
35
|
+
- vpc: Virtual Private Cloud (VPC)
|
|
36
|
+
- slb: Server Load Balancer (SLB)
|
|
37
|
+
- ess: Elastic Scaling (ESS)
|
|
38
|
+
- ros: Resource Orchestration Service (ROS)
|
|
39
|
+
- cbn: Cloud Enterprise Network (CBN)
|
|
40
|
+
- dds: MongoDB Database Service (DDS)
|
|
41
|
+
- r-kvstore: Cloud database Tair (compatible with Redis) (R-KVStore)
|
|
42
|
+
|
|
43
|
+
2. **API Process**
|
|
44
|
+
- Use `ListAPIs` for available APIs
|
|
45
|
+
- Use `GetAPIInfo` for API details
|
|
46
|
+
- Use `CommonAPICaller` to execute
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
### Notes
|
|
51
|
+
- Filter for most appropriate result
|
|
52
|
+
- Choose based on user context and common usage
|
|
53
|
+
- Validate parameters before calls
|
|
54
|
+
- Handle errors gracefully
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
### Common Scenarios
|
|
59
|
+
|
|
60
|
+
1. **Instance Management**
|
|
61
|
+
```
|
|
62
|
+
User: "Start ECS instance i-1234567890abcdef0"
|
|
63
|
+
Action: Use OOS_StartInstances
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
2. **Monitoring**
|
|
67
|
+
```
|
|
68
|
+
User: "Check ECS CPU usage"
|
|
69
|
+
Action: Use CMS_GetCpuUsageData
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
3. **Custom API**
|
|
73
|
+
```
|
|
74
|
+
User: "Create VPC in cn-hangzhou"
|
|
75
|
+
Action: ListAPIs → GetAPIInfo → CommonAPICaller
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Available Tools
|
|
81
|
+
|
|
82
|
+
### ECS (OOS/API)
|
|
83
|
+
- RunCommand: Execute commands on instances
|
|
84
|
+
- StartInstances: Start ECS instances
|
|
85
|
+
- StopInstances: Stop ECS instances
|
|
86
|
+
- RebootInstances: Reboot ECS instances
|
|
87
|
+
- DescribeInstances: List instance details
|
|
88
|
+
- DescribeRegions: List available regions
|
|
89
|
+
- DescribeZones: List available zones
|
|
90
|
+
- DescribeAvailableResource: Check resource inventory
|
|
91
|
+
- DescribeImages: List available images
|
|
92
|
+
- DescribeSecurityGroups: List security groups
|
|
93
|
+
- RunInstances: Create new instances
|
|
94
|
+
- DeleteInstances: Delete instances
|
|
95
|
+
- ResetPassword: Change instance password
|
|
96
|
+
- ReplaceSystemDisk: Change instance OS
|
|
97
|
+
|
|
98
|
+
### VPC (API)
|
|
99
|
+
- DescribeVpcs: List VPCs
|
|
100
|
+
- DescribeVSwitches: List VSwitches
|
|
101
|
+
|
|
102
|
+
### RDS (OOS/API)
|
|
103
|
+
- DescribeDBInstances: List database instances
|
|
104
|
+
- StartDBInstances: Start RDS instances
|
|
105
|
+
- StopDBInstances: Stop RDS instances
|
|
106
|
+
- RestartDBInstances: Restart RDS instances
|
|
107
|
+
|
|
108
|
+
### OSS (API)
|
|
109
|
+
- ListBuckets: List OSS buckets
|
|
110
|
+
- PutBucket: Create bucket
|
|
111
|
+
- DeleteBucket: Delete bucket
|
|
112
|
+
- ListObjects: List bucket contents
|
|
113
|
+
|
|
114
|
+
### CloudMonitor (API)
|
|
115
|
+
- GetCpuUsageData: Get instance CPU usage
|
|
116
|
+
- GetCpuLoadavgData: Get 1m CPU load
|
|
117
|
+
- GetCpuloadavg5mData: Get 5m CPU load
|
|
118
|
+
- GetCpuloadavg15mData: Get 15m CPU load
|
|
119
|
+
- GetMemUsedData: Get memory usage
|
|
120
|
+
- GetMemUsageData: Get memory utilization
|
|
121
|
+
- GetDiskUsageData: Get disk utilization
|
|
122
|
+
- GetDiskTotalData: Get total disk space
|
|
123
|
+
- GetDiskUsedData: Get used disk space
|
|
124
|
+
|
|
125
|
+
Note: (OOS) = Operations Orchestration Service, (API) = Direct API call
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
### Best Practices
|
|
130
|
+
- Use pre-defined tools when possible
|
|
131
|
+
- Follow API rate limits
|
|
132
|
+
- Implement proper error handling
|
|
133
|
+
- Validate all parameters
|
|
134
|
+
- Use appropriate endpoints
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from mcp.server.fastmcp import FastMCP
|
|
2
|
+
import click
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
from alibaba_cloud_ops_mcp_server.tools.common_api_tools import set_custom_service_list
|
|
6
|
+
from alibaba_cloud_ops_mcp_server.config import config
|
|
7
|
+
from alibaba_cloud_ops_mcp_server.tools import cms_tools, oos_tools, oss_tools, api_tools, common_api_tools
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
SUPPORTED_SERVICES_MAP = {
|
|
12
|
+
"ecs": "Elastic Compute Service (ECS)",
|
|
13
|
+
"oos": "Operations Orchestration Service (OOS)",
|
|
14
|
+
"rds": "Relational Database Service (RDS)",
|
|
15
|
+
"vpc": "Virtual Private Cloud (VPC)",
|
|
16
|
+
"slb": "Server Load Balancer (SLB)",
|
|
17
|
+
"ess": "Elastic Scaling (ESS)",
|
|
18
|
+
"ros": "Resource Orchestration Service (ROS)",
|
|
19
|
+
"cbn": "Cloud Enterprise Network (CBN)",
|
|
20
|
+
"dds": "MongoDB Database Service (DDS)",
|
|
21
|
+
"r-kvstore": "Cloud database Tair (compatible with Redis) (R-KVStore)"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@click.command()
|
|
26
|
+
@click.option(
|
|
27
|
+
"--transport",
|
|
28
|
+
type=click.Choice(["stdio", "sse", "streamable-http"]),
|
|
29
|
+
default="stdio",
|
|
30
|
+
help="Transport type",
|
|
31
|
+
)
|
|
32
|
+
@click.option(
|
|
33
|
+
"--port",
|
|
34
|
+
type=int,
|
|
35
|
+
default=8000,
|
|
36
|
+
help="Port number",
|
|
37
|
+
)
|
|
38
|
+
@click.option(
|
|
39
|
+
"--host",
|
|
40
|
+
type=str,
|
|
41
|
+
default="127.0.0.1",
|
|
42
|
+
help="Host",
|
|
43
|
+
)
|
|
44
|
+
@click.option(
|
|
45
|
+
"--services",
|
|
46
|
+
type=str,
|
|
47
|
+
default=None,
|
|
48
|
+
help="Comma-separated list of supported services, e.g., 'ecs,vpc,rds'",
|
|
49
|
+
)
|
|
50
|
+
def main(transport: str, port: int, host: str, services: str):
|
|
51
|
+
# Create an MCP server
|
|
52
|
+
mcp = FastMCP(
|
|
53
|
+
name="alibaba-cloud-ops-mcp-server",
|
|
54
|
+
port=port,
|
|
55
|
+
host=host
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
if services:
|
|
59
|
+
service_keys = [s.strip().lower() for s in services.split(",")]
|
|
60
|
+
service_list = [(key, SUPPORTED_SERVICES_MAP.get(key, key)) for key in service_keys]
|
|
61
|
+
set_custom_service_list(service_list)
|
|
62
|
+
for tool in common_api_tools.tools:
|
|
63
|
+
mcp.add_tool(tool)
|
|
64
|
+
for tool in oos_tools.tools:
|
|
65
|
+
mcp.add_tool(tool)
|
|
66
|
+
for tool in cms_tools.tools:
|
|
67
|
+
mcp.add_tool(tool)
|
|
68
|
+
for tool in oss_tools.tools:
|
|
69
|
+
mcp.add_tool(tool)
|
|
70
|
+
api_tools.create_api_tools(mcp, config)
|
|
71
|
+
|
|
72
|
+
# Initialize and run the server
|
|
73
|
+
logger.debug(f'mcp server is running on {transport} mode.')
|
|
74
|
+
mcp.run(transport=transport)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
if __name__ == "__main__":
|
|
78
|
+
main()
|
|
@@ -24,12 +24,38 @@ type_map = {
|
|
|
24
24
|
'number': float
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
REGION_ENDPOINT_SERVICE = ['ecs', 'oos', 'vpc', 'slb']
|
|
28
|
+
|
|
29
|
+
DOUBLE_ENDPOINT_SERVICE = {
|
|
30
|
+
'rds': ['cn-qingdao', 'cn-beijing', 'cn-hangzhou', 'cn-shanghai', 'cn-shenzhen', 'cn-heyuan', 'cn-guangzhou', 'cn-hongkong'],
|
|
31
|
+
'ess': ['cn-qingdao', 'cn-beijing', 'cn-hangzhou', 'cn-shanghai', 'cn-nanjing', 'cn-shenzhen'],
|
|
32
|
+
'ros': ['cn-qingdao'],
|
|
33
|
+
'dds': ['cn-qingdao', 'cn-beijing', 'cn-wulanchabu', 'cn-hangzhou', 'cn-shanghai', 'cn-shenzhen', 'cn-heyuan', 'cn-guangzhou'],
|
|
34
|
+
'r-kvstore': ['cn-qingdao', 'cn-beijing', 'cn-wulanchabu', 'cn-hangzhou', 'cn-shanghai', 'cn-shenzhen', 'cn-heyuan']
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
CENTRAL_ENDPOINTS_SERVICE = ['cbn']
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _get_service_endpoint(service: str, region_id: str):
|
|
41
|
+
region_id = region_id.lower()
|
|
42
|
+
use_region_endpoint = service in REGION_ENDPOINT_SERVICE or (
|
|
43
|
+
service in DOUBLE_ENDPOINT_SERVICE and region_id in DOUBLE_ENDPOINT_SERVICE[service]
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
if use_region_endpoint:
|
|
47
|
+
return f'{service}.{region_id}.aliyuncs.com'
|
|
48
|
+
elif service in CENTRAL_ENDPOINTS_SERVICE or service in DOUBLE_ENDPOINT_SERVICE:
|
|
49
|
+
return f'{service}.aliyuncs.com'
|
|
50
|
+
else:
|
|
51
|
+
return f'{service}.{region_id}.aliyuncs.com'
|
|
52
|
+
|
|
27
53
|
|
|
28
54
|
def create_client(service: str, region_id: str) -> OpenApiClient:
|
|
29
55
|
config = create_config()
|
|
30
56
|
if isinstance(service, str):
|
|
31
57
|
service = service.lower()
|
|
32
|
-
config.endpoint =
|
|
58
|
+
config.endpoint = _get_service_endpoint(service, region_id.lower())
|
|
33
59
|
return OpenApiClient(config)
|
|
34
60
|
|
|
35
61
|
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
from pydantic import Field
|
|
4
|
+
from alibabacloud_tea_openapi import models as open_api_models
|
|
5
|
+
from alibabacloud_tea_util import models as util_models
|
|
6
|
+
from alibabacloud_tea_openapi.client import Client as OpenApiClient
|
|
7
|
+
from alibabacloud_openapi_util.client import Client as OpenApiUtilClient
|
|
8
|
+
from alibaba_cloud_ops_mcp_server.alibabacloud.api_meta_client import ApiMetaClient
|
|
9
|
+
from alibaba_cloud_ops_mcp_server.alibabacloud.static import PROMPT_UNDERSTANDING
|
|
10
|
+
from alibaba_cloud_ops_mcp_server.tools.api_tools import create_client, _tools_api_call
|
|
11
|
+
|
|
12
|
+
END_STATUSES = ['Success', 'Failed', 'Cancelled']
|
|
13
|
+
|
|
14
|
+
tools = []
|
|
15
|
+
|
|
16
|
+
_CUSTOM_SERVICE_LIST = None
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def set_custom_service_list(service_list):
|
|
22
|
+
global _CUSTOM_SERVICE_LIST
|
|
23
|
+
_CUSTOM_SERVICE_LIST = service_list
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@tools.append
|
|
27
|
+
def PromptUnderstanding() -> str:
|
|
28
|
+
"""
|
|
29
|
+
Always use this tool first to understand the user's query and convert it into suggestions from Alibaba Cloud experts.
|
|
30
|
+
"""
|
|
31
|
+
global _CUSTOM_SERVICE_LIST
|
|
32
|
+
|
|
33
|
+
content = PROMPT_UNDERSTANDING
|
|
34
|
+
if _CUSTOM_SERVICE_LIST:
|
|
35
|
+
import re
|
|
36
|
+
pattern = r'Supported Services\s*:\s*\n(?:\s{3}- .+?\n)+'
|
|
37
|
+
replacement = f"Supported Services:\n - " + "\n - ".join([f"{k}: {v}" for k, v in _CUSTOM_SERVICE_LIST])
|
|
38
|
+
content = re.sub(pattern, replacement, content, flags=re.DOTALL)
|
|
39
|
+
|
|
40
|
+
return content
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@tools.append
|
|
44
|
+
def ListAPIs(
|
|
45
|
+
service: str = Field(description='AlibabaCloud service code')
|
|
46
|
+
):
|
|
47
|
+
"""
|
|
48
|
+
Use PromptUnderstanding tool first to understand the user's query, Get the corresponding API list information through the service name to prepare for the subsequent selection of the appropriate API to call
|
|
49
|
+
"""
|
|
50
|
+
return ApiMetaClient.get_apis_in_service(service)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@tools.append
|
|
54
|
+
def GetAPIInfo(
|
|
55
|
+
service: str = Field(description='AlibabaCloud service code'),
|
|
56
|
+
api: str = Field(description='AlibabaCloud api name'),
|
|
57
|
+
):
|
|
58
|
+
"""
|
|
59
|
+
Use PromptUnderstanding tool first to understand the user's query, After specifying the service name and API name, get the detailed API META of the corresponding API
|
|
60
|
+
"""
|
|
61
|
+
data, version = ApiMetaClient.get_api_meta(service, api)
|
|
62
|
+
return data.get('parameters')
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@tools.append
|
|
66
|
+
def CommonAPICaller(
|
|
67
|
+
service: str = Field(description='AlibabaCloud service code'),
|
|
68
|
+
api: str = Field(description='AlibabaCloud api name'),
|
|
69
|
+
parameters: dict = Field(description='AlibabaCloud ECS instance ID List', default={}),
|
|
70
|
+
):
|
|
71
|
+
"""
|
|
72
|
+
Use PromptUnderstanding tool first to understand the user's query, Perform the actual call by specifying the Service, API, and Parameters
|
|
73
|
+
"""
|
|
74
|
+
return _tools_api_call(service, api, parameters, None)
|
|
@@ -122,8 +122,12 @@ def test_get_api_body_style_none():
|
|
|
122
122
|
|
|
123
123
|
@patch('alibaba_cloud_ops_mcp_server.alibabacloud.api_meta_client.requests.get')
|
|
124
124
|
def test_get_apis_in_service(mock_get):
|
|
125
|
-
|
|
126
|
-
|
|
125
|
+
# 第一次调用 get_service_version 需要 list,第二次 get_response_from_pop_api 需要 dict
|
|
126
|
+
mock_get.return_value.json.side_effect = [
|
|
127
|
+
[{"code": "ecs", "defaultVersion": "2014-05-26"}], # for get_service_version
|
|
128
|
+
{"apis": {"A": {}, "B": {}}} # for get_response_from_pop_api
|
|
129
|
+
]
|
|
130
|
+
apis = api_meta_client.ApiMetaClient.get_apis_in_service('ecs')
|
|
127
131
|
assert set(apis) == {"A", "B"}
|
|
128
132
|
|
|
129
133
|
@patch('alibaba_cloud_ops_mcp_server.alibabacloud.api_meta_client.requests.get')
|
|
@@ -152,7 +156,7 @@ def test_get_api_parameters_empty():
|
|
|
152
156
|
def test_get_apis_in_service_no_apis(mock_get):
|
|
153
157
|
mock_get.return_value.json.return_value = {}
|
|
154
158
|
with pytest.raises(KeyError):
|
|
155
|
-
api_meta_client.ApiMetaClient.get_apis_in_service('ecs'
|
|
159
|
+
api_meta_client.ApiMetaClient.get_apis_in_service('ecs')
|
|
156
160
|
|
|
157
161
|
@patch('alibaba_cloud_ops_mcp_server.alibabacloud.api_meta_client.requests.get')
|
|
158
162
|
def test_get_api_parameters_schema_not_dict(mock_get):
|
|
@@ -172,8 +176,11 @@ def test_get_api_parameters_schema_not_dict(mock_get):
|
|
|
172
176
|
@patch('alibaba_cloud_ops_mcp_server.alibabacloud.api_meta_client.requests.get')
|
|
173
177
|
def test_get_apis_in_service_normal(mock_get):
|
|
174
178
|
"""测试get_apis_in_service方法正常返回API列表"""
|
|
175
|
-
mock_get.return_value.json.
|
|
176
|
-
|
|
179
|
+
mock_get.return_value.json.side_effect = [
|
|
180
|
+
[{"code": "ecs", "defaultVersion": "2014-05-26"}], # for get_service_version
|
|
181
|
+
{"apis": {"DescribeInstances": {}, "StartInstance": {}}} # for get_response_from_pop_api
|
|
182
|
+
]
|
|
183
|
+
apis = api_meta_client.ApiMetaClient.get_apis_in_service('ecs')
|
|
177
184
|
assert set(apis) == {"DescribeInstances", "StartInstance"}
|
|
178
185
|
assert len(apis) == 2
|
|
179
186
|
|
|
@@ -216,8 +223,11 @@ def test_get_api_parameters_schema_not_dict_more_cases(mock_get_meta):
|
|
|
216
223
|
@patch('alibaba_cloud_ops_mcp_server.alibabacloud.api_meta_client.requests.get')
|
|
217
224
|
def test_get_apis_in_service_normal(mock_get):
|
|
218
225
|
"""测试get_apis_in_service方法正常返回API列表"""
|
|
219
|
-
mock_get.return_value.json.
|
|
220
|
-
|
|
226
|
+
mock_get.return_value.json.side_effect = [
|
|
227
|
+
[{"code": "ecs", "defaultVersion": "2014-05-26"}], # for get_service_version
|
|
228
|
+
{"apis": {"DescribeInstances": {}, "StartInstance": {}}} # for get_response_from_pop_api
|
|
229
|
+
]
|
|
230
|
+
apis = api_meta_client.ApiMetaClient.get_apis_in_service('ecs')
|
|
221
231
|
assert set(apis) == {"DescribeInstances", "StartInstance"}
|
|
222
232
|
assert len(apis) == 2
|
|
223
233
|
|
|
@@ -290,3 +300,15 @@ def test_get_ref_api_meta_valid_path(mock_pop_api, mock_std):
|
|
|
290
300
|
}
|
|
291
301
|
}
|
|
292
302
|
assert result == expected
|
|
303
|
+
|
|
304
|
+
@patch('alibaba_cloud_ops_mcp_server.alibabacloud.api_meta_client.ApiMetaClient.get_response_from_pop_api')
|
|
305
|
+
def test_get_all_service_info(mock_get):
|
|
306
|
+
mock_get.return_value = [
|
|
307
|
+
{"code": "ecs", "name": "Elastic Compute Service"},
|
|
308
|
+
{"code": "rds", "name": "Relational Database Service"}
|
|
309
|
+
]
|
|
310
|
+
result = api_meta_client.ApiMetaClient.get_all_service_info()
|
|
311
|
+
assert result == [
|
|
312
|
+
{"code": "ecs", "name": "Elastic Compute Service"},
|
|
313
|
+
{"code": "rds", "name": "Relational Database Service"}
|
|
314
|
+
]
|
{alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/tests/test_server.py
RENAMED
|
@@ -11,9 +11,11 @@ def test_main_run(mock_create_api_tools, mock_FastMCP):
|
|
|
11
11
|
mcp = MagicMock()
|
|
12
12
|
mock_FastMCP.return_value = mcp
|
|
13
13
|
# 调用main函数
|
|
14
|
-
server.main.callback(transport='stdio', port=12345, host='127.0.0.1')
|
|
15
|
-
mock_FastMCP.assert_called_once_with(
|
|
16
|
-
|
|
14
|
+
server.main.callback(transport='stdio', port=12345, host='127.0.0.1', services='ecs')
|
|
15
|
+
mock_FastMCP.assert_called_once_with(
|
|
16
|
+
name='alibaba-cloud-ops-mcp-server',
|
|
17
|
+
port=12345, host='127.0.0.1')
|
|
18
|
+
assert mcp.add_tool.call_count == 7 # common_api_tools 4 + oss/oos/cms 各1
|
|
17
19
|
mock_create_api_tools.assert_called_once()
|
|
18
20
|
mcp.run.assert_called_once_with(transport='stdio')
|
|
19
21
|
|
|
@@ -2,6 +2,10 @@ import pytest
|
|
|
2
2
|
from unittest.mock import patch, MagicMock
|
|
3
3
|
from alibaba_cloud_ops_mcp_server.tools import api_tools
|
|
4
4
|
import json
|
|
5
|
+
from alibaba_cloud_ops_mcp_server.tools import common_api_tools
|
|
6
|
+
from alibaba_cloud_ops_mcp_server.tools.common_api_tools import (
|
|
7
|
+
PromptUnderstanding, ListAPIs, GetAPIInfo, CommonAPICaller
|
|
8
|
+
)
|
|
5
9
|
|
|
6
10
|
def fake_api_meta(post=False, no_summary=False):
|
|
7
11
|
meta = {
|
|
@@ -322,3 +326,64 @@ def test_create_tool_function_with_signature_bind_with_positional_args():
|
|
|
322
326
|
# 验证位置参数被正确绑定
|
|
323
327
|
assert call_args['param1'] == 'value1'
|
|
324
328
|
assert call_args['param2'] == 789
|
|
329
|
+
|
|
330
|
+
def test_prompt_understanding_default():
|
|
331
|
+
# _CUSTOM_SERVICE_LIST 为空
|
|
332
|
+
import alibaba_cloud_ops_mcp_server.tools.common_api_tools as ca
|
|
333
|
+
ca._CUSTOM_SERVICE_LIST = None
|
|
334
|
+
fn = ca.tools[0] # PromptUnderstanding
|
|
335
|
+
result = fn()
|
|
336
|
+
assert isinstance(result, str)
|
|
337
|
+
assert 'Supported Services' in result
|
|
338
|
+
|
|
339
|
+
def test_prompt_understanding_with_custom_service():
|
|
340
|
+
# _CUSTOM_SERVICE_LIST 有值
|
|
341
|
+
import alibaba_cloud_ops_mcp_server.tools.common_api_tools as ca
|
|
342
|
+
ca._CUSTOM_SERVICE_LIST = [('ecs', 'ECS服务'), ('rds', 'RDS服务')]
|
|
343
|
+
fn = ca.tools[0] # PromptUnderstanding
|
|
344
|
+
result = fn()
|
|
345
|
+
assert 'ecs: ECS服务' in result and 'rds: RDS服务' in result
|
|
346
|
+
|
|
347
|
+
@patch('alibaba_cloud_ops_mcp_server.tools.common_api_tools.ApiMetaClient.get_apis_in_service')
|
|
348
|
+
def test_list_apis(mock_get):
|
|
349
|
+
import alibaba_cloud_ops_mcp_server.tools.common_api_tools as ca
|
|
350
|
+
fn = ca.tools[1] # ListAPIs
|
|
351
|
+
mock_get.return_value = ['DescribeInstances', 'StartInstance']
|
|
352
|
+
result = fn('ecs')
|
|
353
|
+
assert result == ['DescribeInstances', 'StartInstance']
|
|
354
|
+
|
|
355
|
+
@patch('alibaba_cloud_ops_mcp_server.tools.common_api_tools.ApiMetaClient.get_api_meta')
|
|
356
|
+
def test_get_api_info(mock_get):
|
|
357
|
+
import alibaba_cloud_ops_mcp_server.tools.common_api_tools as ca
|
|
358
|
+
fn = ca.tools[2] # GetAPIInfo
|
|
359
|
+
mock_get.return_value = ({'parameters': [{'name': 'foo'}]}, '2014-05-26')
|
|
360
|
+
result = fn('ecs', 'DescribeInstances')
|
|
361
|
+
assert result == [{'name': 'foo'}]
|
|
362
|
+
|
|
363
|
+
@patch('alibaba_cloud_ops_mcp_server.tools.common_api_tools._tools_api_call')
|
|
364
|
+
def test_common_api_caller(mock_call):
|
|
365
|
+
import alibaba_cloud_ops_mcp_server.tools.common_api_tools as ca
|
|
366
|
+
fn = ca.tools[3] # CommonAPICaller
|
|
367
|
+
mock_call.return_value = {'result': 'ok'}
|
|
368
|
+
result = fn('ecs', 'DescribeInstances', {'foo': 'bar'})
|
|
369
|
+
assert result == {'result': 'ok'}
|
|
370
|
+
|
|
371
|
+
@patch('alibaba_cloud_ops_mcp_server.tools.api_tools.create_config')
|
|
372
|
+
@patch('alibaba_cloud_ops_mcp_server.tools.api_tools.OpenApiClient', autospec=True)
|
|
373
|
+
def test_create_client(mock_client, mock_create_config):
|
|
374
|
+
from alibaba_cloud_ops_mcp_server.tools import api_tools
|
|
375
|
+
mock_create_config.return_value = MagicMock()
|
|
376
|
+
mock_client.return_value = 'client_obj'
|
|
377
|
+
result = api_tools.create_client('ecs', 'cn-hangzhou')
|
|
378
|
+
assert result == 'client_obj'
|
|
379
|
+
|
|
380
|
+
def test_get_service_endpoint_all_branches():
|
|
381
|
+
from alibaba_cloud_ops_mcp_server.tools.api_tools import _get_service_endpoint
|
|
382
|
+
# REGION_ENDPOINT_SERVICE 分支
|
|
383
|
+
assert _get_service_endpoint('ecs', 'cn-hangzhou') == 'ecs.cn-hangzhou.aliyuncs.com'
|
|
384
|
+
# DOUBLE_ENDPOINT_SERVICE 且 region 匹配
|
|
385
|
+
assert _get_service_endpoint('rds', 'cn-hangzhou') == 'rds.cn-hangzhou.aliyuncs.com'
|
|
386
|
+
# CENTRAL_ENDPOINTS_SERVICE 分支
|
|
387
|
+
assert _get_service_endpoint('cbn', 'cn-hangzhou') == 'cbn.aliyuncs.com'
|
|
388
|
+
# 其它分支
|
|
389
|
+
assert _get_service_endpoint('unknown', 'cn-test') == 'unknown.cn-test.aliyuncs.com'
|
|
@@ -116,7 +116,7 @@ wheels = [
|
|
|
116
116
|
|
|
117
117
|
[[package]]
|
|
118
118
|
name = "alibaba-cloud-ops-mcp-server"
|
|
119
|
-
version = "0.
|
|
119
|
+
version = "0.9.0"
|
|
120
120
|
source = { editable = "." }
|
|
121
121
|
dependencies = [
|
|
122
122
|
{ name = "alibabacloud-cms20190101" },
|
|
@@ -498,66 +498,66 @@ wheels = [
|
|
|
498
498
|
|
|
499
499
|
[[package]]
|
|
500
500
|
name = "coverage"
|
|
501
|
-
version = "7.
|
|
501
|
+
version = "7.9.1"
|
|
502
502
|
source = { registry = "https://pypi.org/simple" }
|
|
503
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
503
|
+
sdist = { url = "https://files.pythonhosted.org/packages/e7/e0/98670a80884f64578f0c22cd70c5e81a6e07b08167721c7487b4d70a7ca0/coverage-7.9.1.tar.gz", hash = "sha256:6cf43c78c4282708a28e466316935ec7489a9c487518a77fa68f716c67909cec", size = 813650 }
|
|
504
504
|
wheels = [
|
|
505
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
506
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
507
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
508
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
509
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
510
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
511
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
512
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
513
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
514
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
515
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
516
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
517
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
518
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
519
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
520
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
521
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
522
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
523
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
524
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
525
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
526
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
527
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
528
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
529
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
530
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
531
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
532
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
533
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
534
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
535
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
536
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
537
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
538
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
539
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
540
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
541
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
542
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
543
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
544
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
545
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
546
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
547
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
548
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
549
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
550
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
551
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
552
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
553
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
554
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
555
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
556
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
557
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
558
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
559
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
560
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
505
|
+
{ url = "https://files.pythonhosted.org/packages/c1/78/1c1c5ec58f16817c09cbacb39783c3655d54a221b6552f47ff5ac9297603/coverage-7.9.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cc94d7c5e8423920787c33d811c0be67b7be83c705f001f7180c7b186dcf10ca", size = 212028 },
|
|
506
|
+
{ url = "https://files.pythonhosted.org/packages/98/db/e91b9076f3a888e3b4ad7972ea3842297a52cc52e73fd1e529856e473510/coverage-7.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16aa0830d0c08a2c40c264cef801db8bc4fc0e1892782e45bcacbd5889270509", size = 212420 },
|
|
507
|
+
{ url = "https://files.pythonhosted.org/packages/0e/d0/2b3733412954576b0aea0a16c3b6b8fbe95eb975d8bfa10b07359ead4252/coverage-7.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf95981b126f23db63e9dbe4cf65bd71f9a6305696fa5e2262693bc4e2183f5b", size = 241529 },
|
|
508
|
+
{ url = "https://files.pythonhosted.org/packages/b3/00/5e2e5ae2e750a872226a68e984d4d3f3563cb01d1afb449a17aa819bc2c4/coverage-7.9.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f05031cf21699785cd47cb7485f67df619e7bcdae38e0fde40d23d3d0210d3c3", size = 239403 },
|
|
509
|
+
{ url = "https://files.pythonhosted.org/packages/37/3b/a2c27736035156b0a7c20683afe7df498480c0dfdf503b8c878a21b6d7fb/coverage-7.9.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb4fbcab8764dc072cb651a4bcda4d11fb5658a1d8d68842a862a6610bd8cfa3", size = 240548 },
|
|
510
|
+
{ url = "https://files.pythonhosted.org/packages/98/f5/13d5fc074c3c0e0dc80422d9535814abf190f1254d7c3451590dc4f8b18c/coverage-7.9.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0f16649a7330ec307942ed27d06ee7e7a38417144620bb3d6e9a18ded8a2d3e5", size = 240459 },
|
|
511
|
+
{ url = "https://files.pythonhosted.org/packages/36/24/24b9676ea06102df824c4a56ffd13dc9da7904478db519efa877d16527d5/coverage-7.9.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:cea0a27a89e6432705fffc178064503508e3c0184b4f061700e771a09de58187", size = 239128 },
|
|
512
|
+
{ url = "https://files.pythonhosted.org/packages/be/05/242b7a7d491b369ac5fee7908a6e5ba42b3030450f3ad62c645b40c23e0e/coverage-7.9.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e980b53a959fa53b6f05343afbd1e6f44a23ed6c23c4b4c56c6662bbb40c82ce", size = 239402 },
|
|
513
|
+
{ url = "https://files.pythonhosted.org/packages/73/e0/4de7f87192fa65c9c8fbaeb75507e124f82396b71de1797da5602898be32/coverage-7.9.1-cp310-cp310-win32.whl", hash = "sha256:70760b4c5560be6ca70d11f8988ee6542b003f982b32f83d5ac0b72476607b70", size = 214518 },
|
|
514
|
+
{ url = "https://files.pythonhosted.org/packages/d5/ab/5e4e2fe458907d2a65fab62c773671cfc5ac704f1e7a9ddd91996f66e3c2/coverage-7.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:a66e8f628b71f78c0e0342003d53b53101ba4e00ea8dabb799d9dba0abbbcebe", size = 215436 },
|
|
515
|
+
{ url = "https://files.pythonhosted.org/packages/60/34/fa69372a07d0903a78ac103422ad34db72281c9fc625eba94ac1185da66f/coverage-7.9.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:95c765060e65c692da2d2f51a9499c5e9f5cf5453aeaf1420e3fc847cc060582", size = 212146 },
|
|
516
|
+
{ url = "https://files.pythonhosted.org/packages/27/f0/da1894915d2767f093f081c42afeba18e760f12fdd7a2f4acbe00564d767/coverage-7.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ba383dc6afd5ec5b7a0d0c23d38895db0e15bcba7fb0fa8901f245267ac30d86", size = 212536 },
|
|
517
|
+
{ url = "https://files.pythonhosted.org/packages/10/d5/3fc33b06e41e390f88eef111226a24e4504d216ab8e5d1a7089aa5a3c87a/coverage-7.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37ae0383f13cbdcf1e5e7014489b0d71cc0106458878ccde52e8a12ced4298ed", size = 245092 },
|
|
518
|
+
{ url = "https://files.pythonhosted.org/packages/0a/39/7aa901c14977aba637b78e95800edf77f29f5a380d29768c5b66f258305b/coverage-7.9.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:69aa417a030bf11ec46149636314c24c8d60fadb12fc0ee8f10fda0d918c879d", size = 242806 },
|
|
519
|
+
{ url = "https://files.pythonhosted.org/packages/43/fc/30e5cfeaf560b1fc1989227adedc11019ce4bb7cce59d65db34fe0c2d963/coverage-7.9.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a4be2a28656afe279b34d4f91c3e26eccf2f85500d4a4ff0b1f8b54bf807338", size = 244610 },
|
|
520
|
+
{ url = "https://files.pythonhosted.org/packages/bf/15/cca62b13f39650bc87b2b92bb03bce7f0e79dd0bf2c7529e9fc7393e4d60/coverage-7.9.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:382e7ddd5289f140259b610e5f5c58f713d025cb2f66d0eb17e68d0a94278875", size = 244257 },
|
|
521
|
+
{ url = "https://files.pythonhosted.org/packages/cd/1a/c0f2abe92c29e1464dbd0ff9d56cb6c88ae2b9e21becdb38bea31fcb2f6c/coverage-7.9.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e5532482344186c543c37bfad0ee6069e8ae4fc38d073b8bc836fc8f03c9e250", size = 242309 },
|
|
522
|
+
{ url = "https://files.pythonhosted.org/packages/57/8d/c6fd70848bd9bf88fa90df2af5636589a8126d2170f3aade21ed53f2b67a/coverage-7.9.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a39d18b3f50cc121d0ce3838d32d58bd1d15dab89c910358ebefc3665712256c", size = 242898 },
|
|
523
|
+
{ url = "https://files.pythonhosted.org/packages/c2/9e/6ca46c7bff4675f09a66fe2797cd1ad6a24f14c9c7c3b3ebe0470a6e30b8/coverage-7.9.1-cp311-cp311-win32.whl", hash = "sha256:dd24bd8d77c98557880def750782df77ab2b6885a18483dc8588792247174b32", size = 214561 },
|
|
524
|
+
{ url = "https://files.pythonhosted.org/packages/a1/30/166978c6302010742dabcdc425fa0f938fa5a800908e39aff37a7a876a13/coverage-7.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:6b55ad10a35a21b8015eabddc9ba31eb590f54adc9cd39bcf09ff5349fd52125", size = 215493 },
|
|
525
|
+
{ url = "https://files.pythonhosted.org/packages/60/07/a6d2342cd80a5be9f0eeab115bc5ebb3917b4a64c2953534273cf9bc7ae6/coverage-7.9.1-cp311-cp311-win_arm64.whl", hash = "sha256:6ad935f0016be24c0e97fc8c40c465f9c4b85cbbe6eac48934c0dc4d2568321e", size = 213869 },
|
|
526
|
+
{ url = "https://files.pythonhosted.org/packages/68/d9/7f66eb0a8f2fce222de7bdc2046ec41cb31fe33fb55a330037833fb88afc/coverage-7.9.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a8de12b4b87c20de895f10567639c0797b621b22897b0af3ce4b4e204a743626", size = 212336 },
|
|
527
|
+
{ url = "https://files.pythonhosted.org/packages/20/20/e07cb920ef3addf20f052ee3d54906e57407b6aeee3227a9c91eea38a665/coverage-7.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5add197315a054e92cee1b5f686a2bcba60c4c3e66ee3de77ace6c867bdee7cb", size = 212571 },
|
|
528
|
+
{ url = "https://files.pythonhosted.org/packages/78/f8/96f155de7e9e248ca9c8ff1a40a521d944ba48bec65352da9be2463745bf/coverage-7.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:600a1d4106fe66f41e5d0136dfbc68fe7200a5cbe85610ddf094f8f22e1b0300", size = 246377 },
|
|
529
|
+
{ url = "https://files.pythonhosted.org/packages/3e/cf/1d783bd05b7bca5c10ded5f946068909372e94615a4416afadfe3f63492d/coverage-7.9.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a876e4c3e5a2a1715a6608906aa5a2e0475b9c0f68343c2ada98110512ab1d8", size = 243394 },
|
|
530
|
+
{ url = "https://files.pythonhosted.org/packages/02/dd/e7b20afd35b0a1abea09fb3998e1abc9f9bd953bee548f235aebd2b11401/coverage-7.9.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81f34346dd63010453922c8e628a52ea2d2ccd73cb2487f7700ac531b247c8a5", size = 245586 },
|
|
531
|
+
{ url = "https://files.pythonhosted.org/packages/4e/38/b30b0006fea9d617d1cb8e43b1bc9a96af11eff42b87eb8c716cf4d37469/coverage-7.9.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:888f8eee13f2377ce86d44f338968eedec3291876b0b8a7289247ba52cb984cd", size = 245396 },
|
|
532
|
+
{ url = "https://files.pythonhosted.org/packages/31/e4/4d8ec1dc826e16791f3daf1b50943e8e7e1eb70e8efa7abb03936ff48418/coverage-7.9.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9969ef1e69b8c8e1e70d591f91bbc37fc9a3621e447525d1602801a24ceda898", size = 243577 },
|
|
533
|
+
{ url = "https://files.pythonhosted.org/packages/25/f4/b0e96c5c38e6e40ef465c4bc7f138863e2909c00e54a331da335faf0d81a/coverage-7.9.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:60c458224331ee3f1a5b472773e4a085cc27a86a0b48205409d364272d67140d", size = 244809 },
|
|
534
|
+
{ url = "https://files.pythonhosted.org/packages/8a/65/27e0a1fa5e2e5079bdca4521be2f5dabf516f94e29a0defed35ac2382eb2/coverage-7.9.1-cp312-cp312-win32.whl", hash = "sha256:5f646a99a8c2b3ff4c6a6e081f78fad0dde275cd59f8f49dc4eab2e394332e74", size = 214724 },
|
|
535
|
+
{ url = "https://files.pythonhosted.org/packages/9b/a8/d5b128633fd1a5e0401a4160d02fa15986209a9e47717174f99dc2f7166d/coverage-7.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:30f445f85c353090b83e552dcbbdad3ec84c7967e108c3ae54556ca69955563e", size = 215535 },
|
|
536
|
+
{ url = "https://files.pythonhosted.org/packages/a3/37/84bba9d2afabc3611f3e4325ee2c6a47cd449b580d4a606b240ce5a6f9bf/coverage-7.9.1-cp312-cp312-win_arm64.whl", hash = "sha256:af41da5dca398d3474129c58cb2b106a5d93bbb196be0d307ac82311ca234342", size = 213904 },
|
|
537
|
+
{ url = "https://files.pythonhosted.org/packages/d0/a7/a027970c991ca90f24e968999f7d509332daf6b8c3533d68633930aaebac/coverage-7.9.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:31324f18d5969feef7344a932c32428a2d1a3e50b15a6404e97cba1cc9b2c631", size = 212358 },
|
|
538
|
+
{ url = "https://files.pythonhosted.org/packages/f2/48/6aaed3651ae83b231556750280682528fea8ac7f1232834573472d83e459/coverage-7.9.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0c804506d624e8a20fb3108764c52e0eef664e29d21692afa375e0dd98dc384f", size = 212620 },
|
|
539
|
+
{ url = "https://files.pythonhosted.org/packages/6c/2a/f4b613f3b44d8b9f144847c89151992b2b6b79cbc506dee89ad0c35f209d/coverage-7.9.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef64c27bc40189f36fcc50c3fb8f16ccda73b6a0b80d9bd6e6ce4cffcd810bbd", size = 245788 },
|
|
540
|
+
{ url = "https://files.pythonhosted.org/packages/04/d2/de4fdc03af5e4e035ef420ed26a703c6ad3d7a07aff2e959eb84e3b19ca8/coverage-7.9.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4fe2348cc6ec372e25adec0219ee2334a68d2f5222e0cba9c0d613394e12d86", size = 243001 },
|
|
541
|
+
{ url = "https://files.pythonhosted.org/packages/f5/e8/eed18aa5583b0423ab7f04e34659e51101135c41cd1dcb33ac1d7013a6d6/coverage-7.9.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34ed2186fe52fcc24d4561041979a0dec69adae7bce2ae8d1c49eace13e55c43", size = 244985 },
|
|
542
|
+
{ url = "https://files.pythonhosted.org/packages/17/f8/ae9e5cce8885728c934eaa58ebfa8281d488ef2afa81c3dbc8ee9e6d80db/coverage-7.9.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:25308bd3d00d5eedd5ae7d4357161f4df743e3c0240fa773ee1b0f75e6c7c0f1", size = 245152 },
|
|
543
|
+
{ url = "https://files.pythonhosted.org/packages/5a/c8/272c01ae792bb3af9b30fac14d71d63371db227980682836ec388e2c57c0/coverage-7.9.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73e9439310f65d55a5a1e0564b48e34f5369bee943d72c88378f2d576f5a5751", size = 243123 },
|
|
544
|
+
{ url = "https://files.pythonhosted.org/packages/8c/d0/2819a1e3086143c094ab446e3bdf07138527a7b88cb235c488e78150ba7a/coverage-7.9.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:37ab6be0859141b53aa89412a82454b482c81cf750de4f29223d52268a86de67", size = 244506 },
|
|
545
|
+
{ url = "https://files.pythonhosted.org/packages/8b/4e/9f6117b89152df7b6112f65c7a4ed1f2f5ec8e60c4be8f351d91e7acc848/coverage-7.9.1-cp313-cp313-win32.whl", hash = "sha256:64bdd969456e2d02a8b08aa047a92d269c7ac1f47e0c977675d550c9a0863643", size = 214766 },
|
|
546
|
+
{ url = "https://files.pythonhosted.org/packages/27/0f/4b59f7c93b52c2c4ce7387c5a4e135e49891bb3b7408dcc98fe44033bbe0/coverage-7.9.1-cp313-cp313-win_amd64.whl", hash = "sha256:be9e3f68ca9edb897c2184ad0eee815c635565dbe7a0e7e814dc1f7cbab92c0a", size = 215568 },
|
|
547
|
+
{ url = "https://files.pythonhosted.org/packages/09/1e/9679826336f8c67b9c39a359352882b24a8a7aee48d4c9cad08d38d7510f/coverage-7.9.1-cp313-cp313-win_arm64.whl", hash = "sha256:1c503289ffef1d5105d91bbb4d62cbe4b14bec4d13ca225f9c73cde9bb46207d", size = 213939 },
|
|
548
|
+
{ url = "https://files.pythonhosted.org/packages/bb/5b/5c6b4e7a407359a2e3b27bf9c8a7b658127975def62077d441b93a30dbe8/coverage-7.9.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0b3496922cb5f4215bf5caaef4cf12364a26b0be82e9ed6d050f3352cf2d7ef0", size = 213079 },
|
|
549
|
+
{ url = "https://files.pythonhosted.org/packages/a2/22/1e2e07279fd2fd97ae26c01cc2186e2258850e9ec125ae87184225662e89/coverage-7.9.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:9565c3ab1c93310569ec0d86b017f128f027cab0b622b7af288696d7ed43a16d", size = 213299 },
|
|
550
|
+
{ url = "https://files.pythonhosted.org/packages/14/c0/4c5125a4b69d66b8c85986d3321520f628756cf524af810baab0790c7647/coverage-7.9.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2241ad5dbf79ae1d9c08fe52b36d03ca122fb9ac6bca0f34439e99f8327ac89f", size = 256535 },
|
|
551
|
+
{ url = "https://files.pythonhosted.org/packages/81/8b/e36a04889dda9960be4263e95e777e7b46f1bb4fc32202612c130a20c4da/coverage-7.9.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bb5838701ca68b10ebc0937dbd0eb81974bac54447c55cd58dea5bca8451029", size = 252756 },
|
|
552
|
+
{ url = "https://files.pythonhosted.org/packages/98/82/be04eff8083a09a4622ecd0e1f31a2c563dbea3ed848069e7b0445043a70/coverage-7.9.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b30a25f814591a8c0c5372c11ac8967f669b97444c47fd794926e175c4047ece", size = 254912 },
|
|
553
|
+
{ url = "https://files.pythonhosted.org/packages/0f/25/c26610a2c7f018508a5ab958e5b3202d900422cf7cdca7670b6b8ca4e8df/coverage-7.9.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2d04b16a6062516df97969f1ae7efd0de9c31eb6ebdceaa0d213b21c0ca1a683", size = 256144 },
|
|
554
|
+
{ url = "https://files.pythonhosted.org/packages/c5/8b/fb9425c4684066c79e863f1e6e7ecebb49e3a64d9f7f7860ef1688c56f4a/coverage-7.9.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7931b9e249edefb07cd6ae10c702788546341d5fe44db5b6108a25da4dca513f", size = 254257 },
|
|
555
|
+
{ url = "https://files.pythonhosted.org/packages/93/df/27b882f54157fc1131e0e215b0da3b8d608d9b8ef79a045280118a8f98fe/coverage-7.9.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:52e92b01041151bf607ee858e5a56c62d4b70f4dac85b8c8cb7fb8a351ab2c10", size = 255094 },
|
|
556
|
+
{ url = "https://files.pythonhosted.org/packages/41/5f/cad1c3dbed8b3ee9e16fa832afe365b4e3eeab1fb6edb65ebbf745eabc92/coverage-7.9.1-cp313-cp313t-win32.whl", hash = "sha256:684e2110ed84fd1ca5f40e89aa44adf1729dc85444004111aa01866507adf363", size = 215437 },
|
|
557
|
+
{ url = "https://files.pythonhosted.org/packages/99/4d/fad293bf081c0e43331ca745ff63673badc20afea2104b431cdd8c278b4c/coverage-7.9.1-cp313-cp313t-win_amd64.whl", hash = "sha256:437c576979e4db840539674e68c84b3cda82bc824dd138d56bead1435f1cb5d7", size = 216605 },
|
|
558
|
+
{ url = "https://files.pythonhosted.org/packages/1f/56/4ee027d5965fc7fc126d7ec1187529cc30cc7d740846e1ecb5e92d31b224/coverage-7.9.1-cp313-cp313t-win_arm64.whl", hash = "sha256:18a0912944d70aaf5f399e350445738a1a20b50fbea788f640751c2ed9208b6c", size = 214392 },
|
|
559
|
+
{ url = "https://files.pythonhosted.org/packages/3e/e5/c723545c3fd3204ebde3b4cc4b927dce709d3b6dc577754bb57f63ca4a4a/coverage-7.9.1-pp39.pp310.pp311-none-any.whl", hash = "sha256:db0f04118d1db74db6c9e1cb1898532c7dcc220f1d2718f058601f7c3f499514", size = 204009 },
|
|
560
|
+
{ url = "https://files.pythonhosted.org/packages/08/b8/7ddd1e8ba9701dea08ce22029917140e6f66a859427406579fd8d0ca7274/coverage-7.9.1-py3-none-any.whl", hash = "sha256:66b974b145aa189516b6bf2d8423e888b742517d37872f6ee4c5be0073bd9a3c", size = 204000 },
|
|
561
561
|
]
|
|
562
562
|
|
|
563
563
|
[package.optional-dependencies]
|
|
@@ -1194,7 +1194,7 @@ wheels = [
|
|
|
1194
1194
|
|
|
1195
1195
|
[[package]]
|
|
1196
1196
|
name = "pytest"
|
|
1197
|
-
version = "8.4.
|
|
1197
|
+
version = "8.4.1"
|
|
1198
1198
|
source = { registry = "https://pypi.org/simple" }
|
|
1199
1199
|
dependencies = [
|
|
1200
1200
|
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
|
@@ -1205,22 +1205,23 @@ dependencies = [
|
|
|
1205
1205
|
{ name = "pygments" },
|
|
1206
1206
|
{ name = "tomli", marker = "python_full_version < '3.11'" },
|
|
1207
1207
|
]
|
|
1208
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
1208
|
+
sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714 }
|
|
1209
1209
|
wheels = [
|
|
1210
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1210
|
+
{ url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474 },
|
|
1211
1211
|
]
|
|
1212
1212
|
|
|
1213
1213
|
[[package]]
|
|
1214
1214
|
name = "pytest-cov"
|
|
1215
|
-
version = "6.
|
|
1215
|
+
version = "6.2.1"
|
|
1216
1216
|
source = { registry = "https://pypi.org/simple" }
|
|
1217
1217
|
dependencies = [
|
|
1218
1218
|
{ name = "coverage", extra = ["toml"] },
|
|
1219
|
+
{ name = "pluggy" },
|
|
1219
1220
|
{ name = "pytest" },
|
|
1220
1221
|
]
|
|
1221
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
1222
|
+
sdist = { url = "https://files.pythonhosted.org/packages/18/99/668cade231f434aaa59bbfbf49469068d2ddd945000621d3d165d2e7dd7b/pytest_cov-6.2.1.tar.gz", hash = "sha256:25cc6cc0a5358204b8108ecedc51a9b57b34cc6b8c967cc2c01a4e00d8a67da2", size = 69432 }
|
|
1222
1223
|
wheels = [
|
|
1223
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1224
|
+
{ url = "https://files.pythonhosted.org/packages/bc/16/4ea354101abb1287856baa4af2732be351c7bee728065aed451b678153fd/pytest_cov-6.2.1-py3-none-any.whl", hash = "sha256:f5bc4c23f42f1cdd23c70b1dab1bbaef4fc505ba950d53e0081d0730dd7e86d5", size = 24644 },
|
|
1224
1225
|
]
|
|
1225
1226
|
|
|
1226
1227
|
[[package]]
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
from mcp.server.fastmcp import FastMCP
|
|
2
|
-
import click
|
|
3
|
-
import logging
|
|
4
|
-
|
|
5
|
-
from alibaba_cloud_ops_mcp_server.config import config
|
|
6
|
-
from alibaba_cloud_ops_mcp_server.tools import cms_tools, oos_tools, oss_tools, api_tools
|
|
7
|
-
|
|
8
|
-
logger = logging.getLogger(__name__)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
@click.command()
|
|
12
|
-
@click.option(
|
|
13
|
-
"--transport",
|
|
14
|
-
type=click.Choice(["stdio", "sse", "streamable-http"]),
|
|
15
|
-
default="stdio",
|
|
16
|
-
help="Transport type",
|
|
17
|
-
)
|
|
18
|
-
@click.option(
|
|
19
|
-
"--port",
|
|
20
|
-
type=int,
|
|
21
|
-
default=8000,
|
|
22
|
-
help="Port number",
|
|
23
|
-
)
|
|
24
|
-
@click.option(
|
|
25
|
-
"--host",
|
|
26
|
-
type=str,
|
|
27
|
-
default="127.0.0.1",
|
|
28
|
-
help="Host",
|
|
29
|
-
)
|
|
30
|
-
def main(transport: str, port: int, host: str):
|
|
31
|
-
# Create an MCP server
|
|
32
|
-
mcp = FastMCP(
|
|
33
|
-
name="alibaba-cloud-ops-mcp-server",
|
|
34
|
-
port=port,
|
|
35
|
-
host=host
|
|
36
|
-
)
|
|
37
|
-
for tool in oos_tools.tools:
|
|
38
|
-
mcp.add_tool(tool)
|
|
39
|
-
for tool in cms_tools.tools:
|
|
40
|
-
mcp.add_tool(tool)
|
|
41
|
-
for tool in oss_tools.tools:
|
|
42
|
-
mcp.add_tool(tool)
|
|
43
|
-
api_tools.create_api_tools(mcp, config)
|
|
44
|
-
|
|
45
|
-
# Initialize and run the server
|
|
46
|
-
logger.debug(f'mcp server is running on {transport} mode.')
|
|
47
|
-
mcp.run(transport=transport)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if __name__ == "__main__":
|
|
51
|
-
main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/image/alibaba-cloud.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{alibaba_cloud_ops_mcp_server-0.8.9 → alibaba_cloud_ops_mcp_server-0.9.0}/tests/test_init.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|