mcpstore 0.1.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.
- mcpstore-0.1.0/LICENSE +21 -0
- mcpstore-0.1.0/MANIFEST.in +11 -0
- mcpstore-0.1.0/PKG-INFO +62 -0
- mcpstore-0.1.0/README.md +35 -0
- mcpstore-0.1.0/pyproject.toml +39 -0
- mcpstore-0.1.0/setup.cfg +4 -0
- mcpstore-0.1.0/setup.py +23 -0
- mcpstore-0.1.0/src/mcpstore/cli/main.py +23 -0
- mcpstore-0.1.0/src/mcpstore/config/config.py +65 -0
- mcpstore-0.1.0/src/mcpstore/core/__init__.py +1 -0
- mcpstore-0.1.0/src/mcpstore/core/client_manager.py +117 -0
- mcpstore-0.1.0/src/mcpstore/core/orchestrator.py +578 -0
- mcpstore-0.1.0/src/mcpstore/core/registry.py +323 -0
- mcpstore-0.1.0/src/mcpstore/core/session_manager.py +84 -0
- mcpstore-0.1.0/src/mcpstore/core/transport.py +378 -0
- mcpstore-0.1.0/src/mcpstore/data/defaults/agent_clients.json +5 -0
- mcpstore-0.1.0/src/mcpstore/data/defaults/client_services.json +54 -0
- mcpstore-0.1.0/src/mcpstore/data/mcp.json +11 -0
- mcpstore-0.1.0/src/mcpstore/plugins/__init__.py +1 -0
- mcpstore-0.1.0/src/mcpstore/plugins/json_mcp.py +238 -0
- mcpstore-0.1.0/src/mcpstore/scripts/__init__.py +1 -0
- mcpstore-0.1.0/src/mcpstore/scripts/app.py +66 -0
- mcpstore-0.1.0/src/mcpstore/scripts/client_registration.py +179 -0
- mcpstore-0.1.0/src/mcpstore/scripts/deps.py +19 -0
- mcpstore-0.1.0/src/mcpstore/scripts/exception_handlers.py +15 -0
- mcpstore-0.1.0/src/mcpstore/scripts/models.py +142 -0
- mcpstore-0.1.0/src/mcpstore/scripts/service_management.py +517 -0
- mcpstore-0.1.0/src/mcpstore/scripts/tool_execution.py +185 -0
- mcpstore-0.1.0/src/mcpstore.egg-info/PKG-INFO +62 -0
- mcpstore-0.1.0/src/mcpstore.egg-info/SOURCES.txt +31 -0
- mcpstore-0.1.0/src/mcpstore.egg-info/dependency_links.txt +1 -0
- mcpstore-0.1.0/src/mcpstore.egg-info/requires.txt +5 -0
- mcpstore-0.1.0/src/mcpstore.egg-info/top_level.txt +1 -0
mcpstore-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 ooooofish
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
include LICENSE
|
|
2
|
+
include README.md
|
|
3
|
+
include MANIFEST.in
|
|
4
|
+
include pyproject.toml
|
|
5
|
+
include setup.py
|
|
6
|
+
recursive-include text2mcp/templates *
|
|
7
|
+
recursive-include text2mcp/core *
|
|
8
|
+
recursive-include text2mcp/utils *
|
|
9
|
+
recursive-include text2mcp/server *
|
|
10
|
+
recursive-include text2mcp/cli *
|
|
11
|
+
recursive-include src/mcpstore *
|
mcpstore-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mcpstore
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A composable, ready-to-use MCP toolkit for agents and rapid integration.
|
|
5
|
+
Home-page: https://github.com/whillhill/mcpstore
|
|
6
|
+
Author: ooooofish
|
|
7
|
+
Author-email: ooooofish <ooooofish@126.com>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
Project-URL: Homepage, https://github.com/whillhill/mcpstore
|
|
10
|
+
Project-URL: Bug Tracker, https://github.com/whillhill/mcpstore/issues
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Requires-Python: >=3.8
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Requires-Dist: fastapi>=0.115.12
|
|
20
|
+
Requires-Dist: fastmcp>=2.7.1
|
|
21
|
+
Requires-Dist: httpx>=0.28.1
|
|
22
|
+
Requires-Dist: pydantic>=2.11.5
|
|
23
|
+
Requires-Dist: uuid>=1.30
|
|
24
|
+
Dynamic: author
|
|
25
|
+
Dynamic: home-page
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# mcpstore
|
|
29
|
+
|
|
30
|
+
A composable, ready-to-use MCP toolkit for agents and rapid integration.
|
|
31
|
+
|
|
32
|
+
## Features
|
|
33
|
+
- Modular MCP service orchestration
|
|
34
|
+
- Fast integration for intelligent agents
|
|
35
|
+
- Extensible plugin and configuration system
|
|
36
|
+
- Built on FastAPI, fastmcp, and httpx
|
|
37
|
+
|
|
38
|
+
## Installation
|
|
39
|
+
```bash
|
|
40
|
+
pip install mcpstore
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Usage
|
|
44
|
+
```python
|
|
45
|
+
# Example usage will be provided in future releases
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Project Structure
|
|
49
|
+
```
|
|
50
|
+
src/mcpstore/
|
|
51
|
+
core/ # Core orchestration and management
|
|
52
|
+
plugins/ # Plugin system
|
|
53
|
+
config/ # Configuration management
|
|
54
|
+
data/ # Data and schema files
|
|
55
|
+
scripts/ # API and CLI scripts
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Contributing
|
|
59
|
+
Contributions are welcome! Please open issues or pull requests on [GitHub](https://github.com/whillhill/mcpstore).
|
|
60
|
+
|
|
61
|
+
## License
|
|
62
|
+
MIT License. See [LICENSE](LICENSE) for details.
|
mcpstore-0.1.0/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# mcpstore
|
|
2
|
+
|
|
3
|
+
A composable, ready-to-use MCP toolkit for agents and rapid integration.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
- Modular MCP service orchestration
|
|
7
|
+
- Fast integration for intelligent agents
|
|
8
|
+
- Extensible plugin and configuration system
|
|
9
|
+
- Built on FastAPI, fastmcp, and httpx
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
```bash
|
|
13
|
+
pip install mcpstore
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
```python
|
|
18
|
+
# Example usage will be provided in future releases
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Project Structure
|
|
22
|
+
```
|
|
23
|
+
src/mcpstore/
|
|
24
|
+
core/ # Core orchestration and management
|
|
25
|
+
plugins/ # Plugin system
|
|
26
|
+
config/ # Configuration management
|
|
27
|
+
data/ # Data and schema files
|
|
28
|
+
scripts/ # API and CLI scripts
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Contributing
|
|
32
|
+
Contributions are welcome! Please open issues or pull requests on [GitHub](https://github.com/whillhill/mcpstore).
|
|
33
|
+
|
|
34
|
+
## License
|
|
35
|
+
MIT License. See [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=42", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "mcpstore"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "A composable, ready-to-use MCP toolkit for agents and rapid integration."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"fastapi>=0.115.12",
|
|
13
|
+
"fastmcp>=2.7.1",
|
|
14
|
+
"httpx>=0.28.1",
|
|
15
|
+
"pydantic>=2.11.5",
|
|
16
|
+
"uuid>=1.30",
|
|
17
|
+
]
|
|
18
|
+
authors = [
|
|
19
|
+
{name = "ooooofish", email = "ooooofish@126.com"}
|
|
20
|
+
]
|
|
21
|
+
license = "MIT"
|
|
22
|
+
classifiers = [
|
|
23
|
+
"Programming Language :: Python :: 3",
|
|
24
|
+
"Programming Language :: Python :: 3.8",
|
|
25
|
+
"Programming Language :: Python :: 3.9",
|
|
26
|
+
"Programming Language :: Python :: 3.10",
|
|
27
|
+
"Operating System :: OS Independent",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.urls]
|
|
31
|
+
"Homepage" = "https://github.com/whillhill/mcpstore"
|
|
32
|
+
"Bug Tracker" = "https://github.com/whillhill/mcpstore/issues"
|
|
33
|
+
|
|
34
|
+
[tool.setuptools]
|
|
35
|
+
include-package-data = true
|
|
36
|
+
license-files = ["LICENSE*"]
|
|
37
|
+
|
|
38
|
+
[tool.setuptools.packages.find]
|
|
39
|
+
where = ["src"]
|
mcpstore-0.1.0/setup.cfg
ADDED
mcpstore-0.1.0/setup.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""
|
|
3
|
+
setup.py for mcpstore
|
|
4
|
+
"""
|
|
5
|
+
from setuptools import setup, find_packages
|
|
6
|
+
|
|
7
|
+
if __name__ == "__main__":
|
|
8
|
+
setup(
|
|
9
|
+
name="mcpstore",
|
|
10
|
+
package_dir={"": "src"},
|
|
11
|
+
packages=find_packages(where="src"),
|
|
12
|
+
include_package_data=True,
|
|
13
|
+
install_requires=[
|
|
14
|
+
"fastapi",
|
|
15
|
+
"fastmcp",
|
|
16
|
+
"httpx"
|
|
17
|
+
],
|
|
18
|
+
author="ooooofish",
|
|
19
|
+
author_email="ooooofish@126.com",
|
|
20
|
+
description="A composable, ready-to-use MCP toolkit for agents and rapid integration.",
|
|
21
|
+
url="https://github.com/whillhill/mcpstore",
|
|
22
|
+
license="MIT",
|
|
23
|
+
)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import argparse
|
|
3
|
+
import uvicorn
|
|
4
|
+
|
|
5
|
+
def main():
|
|
6
|
+
parser = argparse.ArgumentParser(description="mcpstore command line interface")
|
|
7
|
+
subparsers = parser.add_subparsers(dest="command")
|
|
8
|
+
|
|
9
|
+
# api 子命令
|
|
10
|
+
api_parser = subparsers.add_parser("api", help="Start the mcpstore FastAPI server")
|
|
11
|
+
api_parser.add_argument("--host", default="0.0.0.0", help="Host to bind")
|
|
12
|
+
api_parser.add_argument("--port", type=int, default=18200, help="Port to bind")
|
|
13
|
+
api_parser.add_argument("--reload", action="store_true", help="Enable auto-reload")
|
|
14
|
+
|
|
15
|
+
args = parser.parse_args()
|
|
16
|
+
|
|
17
|
+
if args.command == "api":
|
|
18
|
+
uvicorn.run("mcpstore.scripts.app:app", host=args.host, port=args.port, reload=args.reload)
|
|
19
|
+
else:
|
|
20
|
+
parser.print_help()
|
|
21
|
+
|
|
22
|
+
if __name__ == "__main__":
|
|
23
|
+
main()
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
5
|
+
import logging
|
|
6
|
+
from typing import Dict, Any
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
# --- Configuration Constants (default values) ---
|
|
11
|
+
HEARTBEAT_INTERVAL_SECONDS = 60
|
|
12
|
+
HEARTBEAT_TIMEOUT_SECONDS = 180
|
|
13
|
+
HTTP_TIMEOUT_SECONDS = 10
|
|
14
|
+
RECONNECTION_INTERVAL_SECONDS = 60
|
|
15
|
+
REACT_MAX_ITERATIONS = 5
|
|
16
|
+
REACT_ENABLE_TRACE = False
|
|
17
|
+
STREAMABLE_HTTP_ENDPOINT = "/mcp"
|
|
18
|
+
|
|
19
|
+
# @dataclass
|
|
20
|
+
# class LLMConfig:
|
|
21
|
+
# provider: str = "openai_compatible"
|
|
22
|
+
# api_key: str = ""
|
|
23
|
+
# model: str = ""
|
|
24
|
+
# base_url: Optional[str] = None
|
|
25
|
+
|
|
26
|
+
# def load_llm_config() -> LLMConfig:
|
|
27
|
+
# """从环境变量加载LLM配置(仅支持openai兼容接口)"""
|
|
28
|
+
# api_key = os.environ.get("OPENAI_API_KEY", "")
|
|
29
|
+
# model = os.environ.get("OPENAI_MODEL", "")
|
|
30
|
+
# base_url = os.environ.get("OPENAI_BASE_URL")
|
|
31
|
+
# provider = "openai_compatible"
|
|
32
|
+
# if not api_key:
|
|
33
|
+
# logger.warning("OPENAI_API_KEY not set in environment.")
|
|
34
|
+
# if not model:
|
|
35
|
+
# logger.warning("OPENAI_MODEL not set in environment.")
|
|
36
|
+
# return LLMConfig(provider=provider, api_key=api_key, model=model, base_url=base_url)
|
|
37
|
+
|
|
38
|
+
def _get_env_int(var: str, default: int) -> int:
|
|
39
|
+
try:
|
|
40
|
+
return int(os.environ.get(var, default))
|
|
41
|
+
except Exception:
|
|
42
|
+
logger.warning(f"环境变量{var}格式错误,使用默认值{default}")
|
|
43
|
+
return default
|
|
44
|
+
|
|
45
|
+
def _get_env_bool(var: str, default: bool) -> bool:
|
|
46
|
+
val = os.environ.get(var)
|
|
47
|
+
if val is None:
|
|
48
|
+
return default
|
|
49
|
+
return val.lower() in ("1", "true", "yes", "on")
|
|
50
|
+
|
|
51
|
+
def load_app_config() -> Dict[str, Any]:
|
|
52
|
+
"""从环境变量加载全局配置"""
|
|
53
|
+
config_data = {
|
|
54
|
+
"heartbeat_interval": _get_env_int("HEARTBEAT_INTERVAL_SECONDS", HEARTBEAT_INTERVAL_SECONDS),
|
|
55
|
+
"heartbeat_timeout": _get_env_int("HEARTBEAT_TIMEOUT_SECONDS", HEARTBEAT_TIMEOUT_SECONDS),
|
|
56
|
+
"http_timeout": _get_env_int("HTTP_TIMEOUT_SECONDS", HTTP_TIMEOUT_SECONDS),
|
|
57
|
+
"reconnection_interval": _get_env_int("RECONNECTION_INTERVAL_SECONDS", RECONNECTION_INTERVAL_SECONDS),
|
|
58
|
+
"react_max_iterations": _get_env_int("REACT_MAX_ITERATIONS", REACT_MAX_ITERATIONS),
|
|
59
|
+
"react_enable_trace": _get_env_bool("REACT_ENABLE_TRACE", REACT_ENABLE_TRACE),
|
|
60
|
+
"streamable_http_endpoint": os.environ.get("STREAMABLE_HTTP_ENDPOINT", STREAMABLE_HTTP_ENDPOINT),
|
|
61
|
+
}
|
|
62
|
+
# 加载LLM配置
|
|
63
|
+
# config_data["llm_config"] = load_llm_config()
|
|
64
|
+
# logger.info(f"Loaded configuration from environment: {config_data}")
|
|
65
|
+
return config_data
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import json
|
|
3
|
+
import random
|
|
4
|
+
import string
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
from typing import Dict, Any, Optional, List
|
|
7
|
+
import logging
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
CLIENT_SERVICES_PATH = os.path.join(os.path.dirname(__file__), '../config/client_services.json')
|
|
12
|
+
|
|
13
|
+
class ClientManager:
|
|
14
|
+
"""管理客户端配置的类"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, services_path: Optional[str] = None):
|
|
17
|
+
"""
|
|
18
|
+
初始化客户端管理器
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
services_path: 配置文件目录
|
|
22
|
+
"""
|
|
23
|
+
self.services_path = services_path or CLIENT_SERVICES_PATH
|
|
24
|
+
self._ensure_file()
|
|
25
|
+
self.client_services = self.load_all_clients()
|
|
26
|
+
self.main_client_id = "main_client" # 主客户端ID
|
|
27
|
+
|
|
28
|
+
def _ensure_file(self):
|
|
29
|
+
if not os.path.exists(self.services_path):
|
|
30
|
+
with open(self.services_path, 'w', encoding='utf-8') as f:
|
|
31
|
+
json.dump({}, f)
|
|
32
|
+
|
|
33
|
+
def load_all_clients(self) -> Dict[str, Any]:
|
|
34
|
+
"""加载所有客户端配置"""
|
|
35
|
+
with open(self.services_path, 'r', encoding='utf-8') as f:
|
|
36
|
+
return json.load(f)
|
|
37
|
+
|
|
38
|
+
def save_all_clients(self, data: Dict[str, Any]):
|
|
39
|
+
"""保存所有客户端配置"""
|
|
40
|
+
with open(self.services_path, 'w', encoding='utf-8') as f:
|
|
41
|
+
json.dump(data, f, ensure_ascii=False, indent=2)
|
|
42
|
+
|
|
43
|
+
def get_client_config(self, client_id: str) -> Optional[Dict[str, Any]]:
|
|
44
|
+
"""获取客户端配置"""
|
|
45
|
+
all_clients = self.load_all_clients()
|
|
46
|
+
return all_clients.get(client_id)
|
|
47
|
+
|
|
48
|
+
def save_client_config(self, client_id: str, config: Dict[str, Any]):
|
|
49
|
+
"""保存客户端配置"""
|
|
50
|
+
all_clients = self.load_all_clients()
|
|
51
|
+
all_clients[client_id] = config
|
|
52
|
+
self.save_all_clients(all_clients)
|
|
53
|
+
logger.info(f"Saved config for client_id={client_id}")
|
|
54
|
+
|
|
55
|
+
def generate_client_id(self) -> str:
|
|
56
|
+
"""生成唯一的客户端ID"""
|
|
57
|
+
ts = datetime.now().strftime("%Y%m%d%H%M%S")
|
|
58
|
+
return f"client_{ts}"
|
|
59
|
+
|
|
60
|
+
def create_client_config_from_names(self, service_names: List[str], mcp_config: Dict[str, Any]) -> Dict[str, Any]:
|
|
61
|
+
"""从服务名称列表生成新的客户端配置"""
|
|
62
|
+
all_services = mcp_config.get("mcpServers", {})
|
|
63
|
+
selected = {name: all_services[name] for name in service_names if name in all_services}
|
|
64
|
+
return {"mcpServers": selected}
|
|
65
|
+
|
|
66
|
+
def add_client(self, config: Dict[str, Any], client_id: Optional[str] = None) -> str:
|
|
67
|
+
"""
|
|
68
|
+
添加新的客户端配置
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
config: 客户端配置
|
|
72
|
+
client_id: 可选的客户端ID,如果不提供则自动生成
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
使用的客户端ID
|
|
76
|
+
"""
|
|
77
|
+
if not client_id:
|
|
78
|
+
client_id = self.generate_client_id()
|
|
79
|
+
self.client_services[client_id] = config
|
|
80
|
+
self.save_client_config(client_id, config)
|
|
81
|
+
return client_id
|
|
82
|
+
|
|
83
|
+
def remove_client(self, client_id: str) -> bool:
|
|
84
|
+
"""
|
|
85
|
+
移除客户端配置
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
client_id: 要移除的客户端ID
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
是否成功移除
|
|
92
|
+
"""
|
|
93
|
+
if client_id in self.client_services:
|
|
94
|
+
del self.client_services[client_id]
|
|
95
|
+
return self.save_client_config(client_id, {})
|
|
96
|
+
return False
|
|
97
|
+
|
|
98
|
+
def has_client(self, client_id: str) -> bool:
|
|
99
|
+
"""
|
|
100
|
+
检查客户端是否存在
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
client_id: 客户端ID
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
是否存在
|
|
107
|
+
"""
|
|
108
|
+
return client_id in self.client_services
|
|
109
|
+
|
|
110
|
+
def get_all_clients(self) -> Dict[str, Any]:
|
|
111
|
+
"""
|
|
112
|
+
获取所有客户端配置
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
所有客户端配置的字典
|
|
116
|
+
"""
|
|
117
|
+
return self.client_services.copy()
|