ellmos-servercommander-mcp 0.1.0-alpha.1 → 0.1.0-alpha.3

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.
package/README.md CHANGED
@@ -1,72 +1,84 @@
1
1
  # ellmos-servercommander-mcp
2
2
 
3
- Alpha-MCP-Server für Server-Operationen: Deployment-Planung, Mail-Status, Log-Analyse und HTTP-Health-Checks.
3
+ <p align="center">
4
+ <img src="assets/servercommander-logo.jpg" alt="ellmos ServerCommander MCP logo" width="360">
5
+ </p>
4
6
 
5
- ## Status
6
-
7
- - Transport: stdio über das Python-MCP-SDK
8
- - Paketstatus: Alpha-Paket, GitHub-Repo unter `ellmos-ai` vorgesehen
9
- - Aktiver Kern: MCP-Tool-Liste, MCP-Tool-Dispatch, Config-Lader, `sc_logs_analyze`, `sc_health_check`
10
- - Sichere Alpha-Handler: `sc_deploy` erstellt lokale SHA256-Manifeste im Dry-run, `sc_mail_*` führt noch keine IMAP/SMTP-Aktionen aus
7
+ Alpha MCP server for server operations: deployment dry-runs, mail status, access-log analysis, and HTTP health checks.
11
8
 
12
- ## Installation für lokale Tests
9
+ German README: [README_de.md](README_de.md)
13
10
 
14
- ```powershell
15
- cd "C:\Users\User\OneDrive\.TOPICS\.AI\.MCP\ellmos-servercommander-mcp"
16
- $env:PYTHONIOENCODING = "utf-8"
17
- python -m pip install -e ".[dev]"
18
- python -m pytest -q
19
- ```
11
+ ## Status
20
12
 
21
- Keine `.venv` im OneDrive-Ordner anlegen. Falls eine isolierte Umgebung gebraucht wird, außerhalb von OneDrive erstellen.
13
+ - Transport: stdio via the Python MCP SDK
14
+ - Package status: public alpha package under `ellmos-ai`
15
+ - Current core: MCP tool listing, MCP tool dispatch, config loading, `sc_logs_analyze`, `sc_health_check`
16
+ - Safe alpha handlers: `sc_deploy` builds local SHA256 manifests in dry-run mode; `sc_mail_*` does not perform IMAP/SMTP operations yet
17
+ - i18n: localized MCP tool descriptions for `en`, `de`, `es`, `zh`, `ja`, `ru` with English fallback
22
18
 
23
- ## npm Alpha
19
+ ## Install
24
20
 
25
- Das npm-Paket enthält einen Node-Wrapper, der den Python-Server startet. Voraussetzung bleibt Python 3.10+ mit installiertem Python-Paket `mcp>=1.0.0`.
21
+ The npm package contains a Node wrapper that starts the Python server. You still need Python 3.10+ and the Python package `mcp>=1.0.0`.
26
22
 
27
23
  ```powershell
28
24
  npm install -g ellmos-servercommander-mcp@alpha
29
25
  ellmos-servercommander
30
26
  ```
31
27
 
32
- ## Start
28
+ For local development:
33
29
 
34
30
  ```powershell
35
- ellmos-servercommander
31
+ cd "C:\Users\User\OneDrive\.TOPICS\.AI\.MCP\ellmos-servercommander-mcp"
32
+ $env:PYTHONIOENCODING = "utf-8"
33
+ python -m pip install -e ".[dev]"
34
+ python -m pytest -q
36
35
  ```
37
36
 
38
- Oder direkt aus dem Quellbaum:
37
+ Do not create a `.venv` inside a OneDrive-synced folder. If you need an isolated environment, create it outside OneDrive.
38
+
39
+ ## Start From Source
39
40
 
40
41
  ```powershell
41
42
  $env:PYTHONPATH = "src"
42
43
  python -m servercommander.server
43
44
  ```
44
45
 
45
- ## Konfiguration
46
+ ## Configuration
46
47
 
47
- Beispiel: [config/servercommander.example.toml](config/servercommander.example.toml)
48
+ Example: [config/servercommander.example.toml](config/servercommander.example.toml)
48
49
 
49
- Standardpfade:
50
+ Default paths:
50
51
 
51
52
  - `%USERPROFILE%\.servercommander\config.toml`
52
53
  - `%USERPROFILE%\.config\servercommander\config.toml`
53
- - Override per `SERVERCOMMANDER_CONFIG`
54
+ - override with `SERVERCOMMANDER_CONFIG`
55
+
56
+ Language can be configured with `[server].language`, `SERVERCOMMANDER_LANG`, or `SERVERCOMMANDER_LOCALE`.
57
+
58
+ ```toml
59
+ [server]
60
+ name = "ellmos-servercommander"
61
+ language = "en" # en, de, es, zh, ja, ru
62
+ ```
54
63
 
55
- Secrets sollen als Umgebungsvariablen referenziert werden, zum Beispiel `$MAIL_PASSWORD` oder `$SFTP_PASSWORD`.
64
+ Secrets should be referenced through environment variables, for example `$MAIL_PASSWORD` or `$SFTP_PASSWORD`.
56
65
 
57
66
  ## Tools
58
67
 
59
- - `sc_health_check`: prüft HTTP-Endpunkte und meldet Status-Code plus Latenz
60
- - `sc_logs_analyze`: analysiert Apache-/Nginx-Access-Logs aus Text oder Datei
61
- - `sc_deploy`: erstellt im Alpha-Modus einen Deployment-Plan mit lokalem SHA256-Manifest, führt aber noch keinen Upload aus
62
- - `sc_deploy_status`: zeigt konfigurierte Deploy-Profile und den noch fehlenden History-Status
63
- - `sc_mail_list`, `sc_mail_read`, `sc_mail_send`, `sc_mail_search`: liefern aktuell sichere Alpha-Statusantworten ohne IMAP/SMTP-Verbindung
68
+ - `sc_health_check`: checks HTTP endpoints and reports status code plus latency
69
+ - `sc_logs_analyze`: analyzes Apache/Nginx access logs from inline text or a local file
70
+ - `sc_deploy`: creates a deployment plan with a local SHA256 manifest, but does not upload yet
71
+ - `sc_deploy_status`: shows configured deploy profiles and the current alpha history status
72
+ - `sc_mail_list`, `sc_mail_read`, `sc_mail_send`, `sc_mail_search`: safe alpha status responses without IMAP/SMTP connections
64
73
 
65
- ## Entwicklung
74
+ ## Development
66
75
 
67
76
  ```powershell
68
77
  $env:PYTHONIOENCODING = "utf-8"
78
+ $env:PYTHONDONTWRITEBYTECODE = "1"
69
79
  python -m pytest -q
80
+ npm run smoke
81
+ npm pack --dry-run
70
82
  ```
71
83
 
72
- Der nächste sinnvolle Schritt ist die Extraktion der echten SFTP-, IMAP/SMTP- und erweiterten Traffic-Module aus `.UMBRUCH` in credential-freie Adapter mit lokalen Tests.
84
+ Next useful step: extract real SFTP, IMAP/SMTP, and extended traffic-analysis modules from `.UMBRUCH` into credential-free adapters with local tests.
package/README_de.md ADDED
@@ -0,0 +1,84 @@
1
+ # ellmos-servercommander-mcp
2
+
3
+ <p align="center">
4
+ <img src="assets/servercommander-logo.jpg" alt="ellmos ServerCommander MCP Logo" width="360">
5
+ </p>
6
+
7
+ Alpha-MCP-Server für Server-Operationen: Deployment-Dry-runs, Mail-Status, Access-Log-Analyse und HTTP-Health-Checks.
8
+
9
+ Englische Standard-README: [README.md](README.md)
10
+
11
+ ## Status
12
+
13
+ - Transport: stdio über das Python-MCP-SDK
14
+ - Paketstatus: öffentliches Alpha-Paket unter `ellmos-ai`
15
+ - Aktiver Kern: MCP-Tool-Liste, MCP-Tool-Dispatch, Config-Lader, `sc_logs_analyze`, `sc_health_check`
16
+ - Sichere Alpha-Handler: `sc_deploy` erstellt lokale SHA256-Manifeste im Dry-run, `sc_mail_*` führt noch keine IMAP/SMTP-Aktionen aus
17
+ - i18n: lokalisierte MCP-Tool-Beschreibungen für `en`, `de`, `es`, `zh`, `ja`, `ru` mit Englisch-Fallback
18
+
19
+ ## Installation
20
+
21
+ Das npm-Paket enthält einen Node-Wrapper, der den Python-Server startet. Voraussetzung bleibt Python 3.10+ mit installiertem Python-Paket `mcp>=1.0.0`.
22
+
23
+ ```powershell
24
+ npm install -g ellmos-servercommander-mcp@alpha
25
+ ellmos-servercommander
26
+ ```
27
+
28
+ Für lokale Entwicklung:
29
+
30
+ ```powershell
31
+ cd "C:\Users\User\OneDrive\.TOPICS\.AI\.MCP\ellmos-servercommander-mcp"
32
+ $env:PYTHONIOENCODING = "utf-8"
33
+ python -m pip install -e ".[dev]"
34
+ python -m pytest -q
35
+ ```
36
+
37
+ Keine `.venv` im OneDrive-Ordner anlegen. Falls eine isolierte Umgebung gebraucht wird, außerhalb von OneDrive erstellen.
38
+
39
+ ## Start Aus Dem Quellbaum
40
+
41
+ ```powershell
42
+ $env:PYTHONPATH = "src"
43
+ python -m servercommander.server
44
+ ```
45
+
46
+ ## Konfiguration
47
+
48
+ Beispiel: [config/servercommander.example.toml](config/servercommander.example.toml)
49
+
50
+ Standardpfade:
51
+
52
+ - `%USERPROFILE%\.servercommander\config.toml`
53
+ - `%USERPROFILE%\.config\servercommander\config.toml`
54
+ - Override per `SERVERCOMMANDER_CONFIG`
55
+
56
+ Die Sprache kann über `[server].language`, `SERVERCOMMANDER_LANG` oder `SERVERCOMMANDER_LOCALE` gesetzt werden.
57
+
58
+ ```toml
59
+ [server]
60
+ name = "ellmos-servercommander"
61
+ language = "de" # en, de, es, zh, ja, ru
62
+ ```
63
+
64
+ Secrets sollen als Umgebungsvariablen referenziert werden, zum Beispiel `$MAIL_PASSWORD` oder `$SFTP_PASSWORD`.
65
+
66
+ ## Tools
67
+
68
+ - `sc_health_check`: prüft HTTP-Endpunkte und meldet Status-Code plus Latenz
69
+ - `sc_logs_analyze`: analysiert Apache-/Nginx-Access-Logs aus Text oder Datei
70
+ - `sc_deploy`: erstellt einen Deployment-Plan mit lokalem SHA256-Manifest, führt aber noch keinen Upload aus
71
+ - `sc_deploy_status`: zeigt konfigurierte Deploy-Profile und den aktuellen Alpha-History-Status
72
+ - `sc_mail_list`, `sc_mail_read`, `sc_mail_send`, `sc_mail_search`: sichere Alpha-Statusantworten ohne IMAP/SMTP-Verbindung
73
+
74
+ ## Entwicklung
75
+
76
+ ```powershell
77
+ $env:PYTHONIOENCODING = "utf-8"
78
+ $env:PYTHONDONTWRITEBYTECODE = "1"
79
+ python -m pytest -q
80
+ npm run smoke
81
+ npm pack --dry-run
82
+ ```
83
+
84
+ Der nächste sinnvolle Schritt ist die Extraktion der echten SFTP-, IMAP/SMTP- und erweiterten Traffic-Module aus `.UMBRUCH` in credential-freie Adapter mit lokalen Tests.
Binary file
@@ -1,17 +1,19 @@
1
- # ellmos-servercommander-mcp — Konfiguration
2
- # Kopieren nach ~/.servercommander/config.toml und anpassen.
1
+ # ellmos-servercommander-mcp configuration
2
+ # Copy to ~/.servercommander/config.toml and adjust.
3
3
 
4
4
  [server]
5
5
  name = "ellmos-servercommander"
6
+ # Tool metadata language: en, de, es, zh, ja, ru
7
+ language = "en"
6
8
 
7
- # --- Deploy-Profile ---
9
+ # --- Deploy profiles ---
8
10
  [deploy.profiles.example_site]
9
11
  host = "sftp.example.com"
10
12
  user = "deploy-user"
11
13
  remote_path = "/var/www/example"
12
14
  local_path = "./dist"
13
15
  protocol = "sftp"
14
- # password = "$SFTP_PASSWORD" # Env-Variable referenzieren
16
+ # password = "$SFTP_PASSWORD" # Use environment variables for secrets.
15
17
 
16
18
  # [deploy.profiles.other]
17
19
  # host = "..."
@@ -26,11 +28,11 @@ username = "$MAIL_USER"
26
28
  password = "$MAIL_PASSWORD"
27
29
  cache_db = "~/.servercommander/mail_cache.db"
28
30
 
29
- # --- Log-Analyse ---
31
+ # --- Log analysis ---
30
32
  [logs]
31
33
  default_format = "apache" # apache | nginx
32
34
 
33
- # --- Health-Checks ---
35
+ # --- Health checks ---
34
36
  [health]
35
37
  timeout = 5
36
38
  endpoints = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ellmos-servercommander-mcp",
3
- "version": "0.1.0-alpha.1",
3
+ "version": "0.1.0-alpha.3",
4
4
  "description": "Alpha MCP server for server operations: deploy dry-runs, mail status, log analysis, and health checks.",
5
5
  "type": "commonjs",
6
6
  "license": "MIT",
@@ -17,10 +17,12 @@
17
17
  "ellmos-servercommander": "bin/ellmos-servercommander.js"
18
18
  },
19
19
  "files": [
20
+ "assets/",
20
21
  "bin/",
21
22
  "config/",
22
23
  "src/",
23
24
  "README.md",
25
+ "README_de.md",
24
26
  "KONZEPT.md",
25
27
  "pyproject.toml"
26
28
  ],
@@ -29,6 +31,7 @@
29
31
  "server",
30
32
  "deploy",
31
33
  "logs",
34
+ "i18n",
32
35
  "health-checks",
33
36
  "ellmos"
34
37
  ],
package/pyproject.toml CHANGED
@@ -4,13 +4,13 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "ellmos-servercommander-mcp"
7
- version = "0.1.0"
7
+ version = "0.1.0a3"
8
8
  description = "MCP server for server operations: deploy, mail, log analysis, health checks."
9
9
  readme = "README.md"
10
10
  license = "MIT"
11
11
  requires-python = ">=3.10"
12
12
  authors = [{ name = "Lukas Geiger" }]
13
- keywords = ["mcp", "deploy", "server-management", "ellmos"]
13
+ keywords = ["mcp", "deploy", "server-management", "i18n", "ellmos"]
14
14
  dependencies = [
15
15
  "mcp>=1.0.0",
16
16
  ]
@@ -1,3 +1,3 @@
1
- """ellmos-servercommander-mcp Server operations via MCP."""
1
+ """ellmos-servercommander-mcp - server operations via MCP."""
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "0.1.0a3"
@@ -22,6 +22,7 @@ DEFAULT_CONFIG_PATHS = [
22
22
  @dataclass
23
23
  class ServerCommanderConfig:
24
24
  server_name: str = "ellmos-servercommander"
25
+ language: str = "en"
25
26
  deploy_profiles: dict[str, dict[str, Any]] = field(default_factory=dict)
26
27
  mail: dict[str, Any] = field(default_factory=dict)
27
28
  logs: dict[str, Any] = field(default_factory=dict)
@@ -45,7 +46,7 @@ def load_config(path: str | Path | None = None) -> ServerCommanderConfig:
45
46
  break
46
47
 
47
48
  if path is None or not Path(path).exists():
48
- return ServerCommanderConfig()
49
+ return ServerCommanderConfig(language=_env_language("en"))
49
50
 
50
51
  with open(path, "rb") as f:
51
52
  raw = tomllib.load(f)
@@ -53,9 +54,11 @@ def load_config(path: str | Path | None = None) -> ServerCommanderConfig:
53
54
  deploy = raw.get("deploy", {})
54
55
  profiles = deploy.get("profiles", {}) if isinstance(deploy, dict) else {}
55
56
  server = raw.get("server", {})
57
+ language = _env_language(server.get("language") or server.get("locale") or "en")
56
58
 
57
59
  return ServerCommanderConfig(
58
60
  server_name=server.get("name", "ellmos-servercommander"),
61
+ language=language,
59
62
  deploy_profiles=profiles if isinstance(profiles, dict) else {},
60
63
  mail=raw.get("mail", {}),
61
64
  logs=raw.get("logs", {}),
@@ -69,3 +72,7 @@ def resolve_env_value(value: Any) -> Any:
69
72
  if isinstance(value, str) and value.startswith("$") and len(value) > 1:
70
73
  return os.environ.get(value[1:], "")
71
74
  return value
75
+
76
+
77
+ def _env_language(default: str) -> str:
78
+ return os.environ.get("SERVERCOMMANDER_LANG") or os.environ.get("SERVERCOMMANDER_LOCALE") or default
@@ -0,0 +1,98 @@
1
+ """Locale helpers for ServerCommander MCP tool metadata."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+
7
+ DEFAULT_LOCALE = "en"
8
+ SUPPORTED_LOCALES = ("en", "de", "es", "zh", "ja", "ru")
9
+
10
+ ALIASES = {
11
+ "en-us": "en",
12
+ "en-gb": "en",
13
+ "de-de": "de",
14
+ "de-at": "de",
15
+ "de-ch": "de",
16
+ "es-es": "es",
17
+ "es-mx": "es",
18
+ "zh-cn": "zh",
19
+ "zh-hans": "zh",
20
+ "ja-jp": "ja",
21
+ "ru-ru": "ru",
22
+ }
23
+
24
+ TRANSLATIONS: dict[str, dict[str, str]] = {
25
+ "de": {
26
+ "tool.sc_deploy": "Erstellt einen sicheren Deployment-Plan. Alpha: Ausführung nur als Dry-run.",
27
+ "tool.sc_deploy_status": "Zeigt konfigurierte Deployment-Profile und Alpha-History-Status.",
28
+ "tool.sc_mail_list": "Alpha-Mail-Status für das Auflisten eines IMAP-Ordners.",
29
+ "tool.sc_mail_read": "Alpha-Mail-Status für das Lesen einer Nachricht.",
30
+ "tool.sc_mail_send": "Alpha-Mail-Status für das Senden einer E-Mail; sendet noch nicht.",
31
+ "tool.sc_mail_search": "Alpha-Mail-Status für die Mail-Suche.",
32
+ "tool.sc_logs_analyze": "Analysiert Apache-/Nginx-Access-Logs aus Text oder Datei.",
33
+ "tool.sc_health_check": "Prüft HTTP-Endpunkte und meldet Status-Codes plus Latenz.",
34
+ },
35
+ "es": {
36
+ "tool.sc_deploy": "Crea un plan de despliegue seguro. Alpha: solo dry-run.",
37
+ "tool.sc_deploy_status": "Muestra perfiles de despliegue y estado de historial alpha.",
38
+ "tool.sc_mail_list": "Estado alpha para listar una carpeta IMAP.",
39
+ "tool.sc_mail_read": "Estado alpha para leer un mensaje.",
40
+ "tool.sc_mail_send": "Estado alpha para enviar correo; aún no envía.",
41
+ "tool.sc_mail_search": "Estado alpha para buscar correo.",
42
+ "tool.sc_logs_analyze": "Analiza logs de acceso Apache/Nginx desde texto o archivo.",
43
+ "tool.sc_health_check": "Comprueba endpoints HTTP y devuelve código de estado y latencia.",
44
+ },
45
+ "zh": {
46
+ "tool.sc_deploy": "创建安全部署计划。Alpha 版仅支持 dry-run。",
47
+ "tool.sc_deploy_status": "显示部署配置和 Alpha 历史状态。",
48
+ "tool.sc_mail_list": "用于列出 IMAP 文件夹的 Alpha 邮件状态。",
49
+ "tool.sc_mail_read": "用于读取邮件的 Alpha 状态。",
50
+ "tool.sc_mail_send": "用于发送邮件的 Alpha 状态;当前不会真正发送。",
51
+ "tool.sc_mail_search": "用于搜索邮件的 Alpha 状态。",
52
+ "tool.sc_logs_analyze": "从文本或文件分析 Apache/Nginx 访问日志。",
53
+ "tool.sc_health_check": "检查 HTTP 端点并返回状态码和延迟。",
54
+ },
55
+ "ja": {
56
+ "tool.sc_deploy": "安全なデプロイ計画を作成します。Alpha では dry-run のみです。",
57
+ "tool.sc_deploy_status": "設定済みデプロイプロファイルと Alpha 履歴状態を表示します。",
58
+ "tool.sc_mail_list": "IMAP フォルダ一覧用の Alpha メール状態を返します。",
59
+ "tool.sc_mail_read": "メッセージ読み取り用の Alpha メール状態を返します。",
60
+ "tool.sc_mail_send": "メール送信用の Alpha 状態を返します。まだ送信しません。",
61
+ "tool.sc_mail_search": "メール検索用の Alpha 状態を返します。",
62
+ "tool.sc_logs_analyze": "テキストまたはファイルから Apache/Nginx アクセスログを分析します。",
63
+ "tool.sc_health_check": "HTTP エンドポイントを確認し、ステータスコードとレイテンシを返します。",
64
+ },
65
+ "ru": {
66
+ "tool.sc_deploy": "Создает безопасный план деплоя. Alpha: только dry-run.",
67
+ "tool.sc_deploy_status": "Показывает профили деплоя и alpha-статус истории.",
68
+ "tool.sc_mail_list": "Alpha-статус для просмотра папки IMAP.",
69
+ "tool.sc_mail_read": "Alpha-статус для чтения сообщения.",
70
+ "tool.sc_mail_send": "Alpha-статус отправки почты; пока не отправляет.",
71
+ "tool.sc_mail_search": "Alpha-статус поиска почты.",
72
+ "tool.sc_logs_analyze": "Анализирует access-логи Apache/Nginx из текста или файла.",
73
+ "tool.sc_health_check": "Проверяет HTTP endpoints и возвращает коды статуса и задержку.",
74
+ },
75
+ }
76
+
77
+
78
+ def normalize_locale(locale: str | None) -> str:
79
+ if not locale:
80
+ return DEFAULT_LOCALE
81
+ normalized = locale.strip().lower().replace("_", "-")
82
+ normalized = ALIASES.get(normalized, normalized.split("-", 1)[0])
83
+ if normalized in SUPPORTED_LOCALES:
84
+ return normalized
85
+ return DEFAULT_LOCALE
86
+
87
+
88
+ @dataclass(frozen=True)
89
+ class I18n:
90
+ locale: str = DEFAULT_LOCALE
91
+
92
+ def __post_init__(self) -> None:
93
+ object.__setattr__(self, "locale", normalize_locale(self.locale))
94
+
95
+ def t(self, key: str, default: str | None = None) -> str:
96
+ if self.locale == DEFAULT_LOCALE:
97
+ return default or key
98
+ return TRANSLATIONS.get(self.locale, {}).get(key) or default or key
@@ -15,6 +15,7 @@ from mcp.server.stdio import stdio_server
15
15
  from servercommander.config import ServerCommanderConfig, load_config
16
16
  from servercommander.deploy import sc_deploy, sc_deploy_status
17
17
  from servercommander.health import sc_health_check
18
+ from servercommander.i18n import I18n
18
19
  from servercommander.logs import sc_logs_analyze
19
20
  from servercommander.mail import sc_mail_list, sc_mail_read, sc_mail_search, sc_mail_send
20
21
  from servercommander.tooling import ToolDefinition
@@ -31,9 +32,17 @@ class ServerCommanderRegistry:
31
32
  self.config = config
32
33
  self._tools = build_tools(config)
33
34
  self._handlers = {tool.name: tool.handler for tool in self._tools}
35
+ self.i18n = I18n(config.language)
34
36
 
35
37
  def list_tools(self) -> list[types.Tool]:
36
- return [tool.as_mcp_tool() for tool in self._tools]
38
+ return [
39
+ types.Tool(
40
+ name=tool.name,
41
+ description=self.i18n.t(f"tool.{tool.name}", tool.description),
42
+ inputSchema=tool.input_schema,
43
+ )
44
+ for tool in self._tools
45
+ ]
37
46
 
38
47
  async def call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> dict[str, Any]:
39
48
  handler = self._handlers.get(name)