ellmos-servercommander-mcp 0.1.0-alpha.4 → 0.1.0-alpha.6
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/KONZEPT.md +4 -4
- package/README.md +57 -11
- package/README_de.md +57 -11
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/src/servercommander/__init__.py +1 -1
- package/src/servercommander/deploy.py +24 -0
- package/src/servercommander/logs.py +28 -1
- package/src/servercommander/mail.py +17 -1
package/KONZEPT.md
CHANGED
|
@@ -83,9 +83,9 @@ endpoints = [
|
|
|
83
83
|
|
|
84
84
|
## Quellmodule
|
|
85
85
|
|
|
86
|
-
| Modul |
|
|
86
|
+
| Modul | Herkunft | LoC | Dependencies |
|
|
87
87
|
|---|---|---|---|
|
|
88
|
-
| deploy.py |
|
|
89
|
-
| cli.py (Mail) |
|
|
90
|
-
| traffic_analyzer.py |
|
|
88
|
+
| deploy.py | interne Extraktionsnotiz | ~221 | paramiko (SFTP) |
|
|
89
|
+
| cli.py (Mail) | interne Extraktionsnotiz | ~516 | stdlib (imaplib, smtplib) |
|
|
90
|
+
| traffic_analyzer.py | interne Extraktionsnotiz | ~300 | stdlib |
|
|
91
91
|
| health.py | neu | ~50 | stdlib (urllib) |
|
package/README.md
CHANGED
|
@@ -8,33 +8,47 @@ Alpha MCP server for server operations: deployment dry-runs, mail status, access
|
|
|
8
8
|
|
|
9
9
|
German README: [README_de.md](README_de.md)
|
|
10
10
|
|
|
11
|
+
*Part of the [ellmos-ai](https://github.com/ellmos-ai) family.*
|
|
12
|
+
|
|
13
|
+
[](https://opensource.org/licenses/MIT)
|
|
14
|
+
[](https://www.npmjs.com/package/ellmos-servercommander-mcp)
|
|
15
|
+
[](https://www.python.org/)
|
|
16
|
+
[](https://nodejs.org/)
|
|
17
|
+
[](https://modelcontextprotocol.io/)
|
|
18
|
+
[](https://www.npmjs.com/package/ellmos-servercommander-mcp)
|
|
19
|
+
|
|
20
|
+
**Discoverability:** Published on [npm](https://www.npmjs.com/package/ellmos-servercommander-mcp) as `ellmos-servercommander-mcp` and maintained in the [`ellmos-ai`](https://github.com/ellmos-ai) organization.
|
|
21
|
+
|
|
11
22
|
## Status
|
|
12
23
|
|
|
13
24
|
- Transport: stdio via the Python MCP SDK
|
|
14
25
|
- Package status: public alpha package under `ellmos-ai`
|
|
15
|
-
- Current core: MCP tool listing, MCP tool dispatch, config loading,
|
|
16
|
-
- Safe alpha handlers: `sc_deploy` builds local SHA256 manifests in dry-run mode; `sc_mail_*`
|
|
26
|
+
- Current core: MCP tool listing, MCP tool dispatch, config loading, HTTP health checks, richer access-log analysis
|
|
27
|
+
- Safe alpha handlers: `sc_deploy` builds local SHA256 manifests and configuration diagnostics in dry-run mode; `sc_mail_*` reports mail configuration gaps without IMAP/SMTP operations
|
|
17
28
|
- i18n: localized MCP tool descriptions, input-schema field descriptions, and unknown-tool errors for `en`, `de`, `es`, `zh`, `ja`, `ru` with English fallback
|
|
18
29
|
|
|
19
30
|
## Install
|
|
20
31
|
|
|
21
32
|
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`.
|
|
22
33
|
|
|
34
|
+
### Option 1: Install From npm
|
|
35
|
+
|
|
23
36
|
```powershell
|
|
24
37
|
npm install -g ellmos-servercommander-mcp@alpha
|
|
25
38
|
ellmos-servercommander
|
|
26
39
|
```
|
|
27
40
|
|
|
28
|
-
|
|
41
|
+
### Option 2: Install From Source
|
|
29
42
|
|
|
30
43
|
```powershell
|
|
31
|
-
|
|
44
|
+
git clone https://github.com/ellmos-ai/ellmos-servercommander-mcp.git
|
|
45
|
+
cd ellmos-servercommander-mcp
|
|
32
46
|
$env:PYTHONIOENCODING = "utf-8"
|
|
33
47
|
python -m pip install -e ".[dev]"
|
|
34
48
|
python -m pytest -q
|
|
35
49
|
```
|
|
36
50
|
|
|
37
|
-
|
|
51
|
+
Avoid creating a `.venv` inside cloud-synced folders if your sync client locks files. If you need an isolated environment, create it outside that folder.
|
|
38
52
|
|
|
39
53
|
## Start From Source
|
|
40
54
|
|
|
@@ -43,7 +57,39 @@ $env:PYTHONPATH = "src"
|
|
|
43
57
|
python -m servercommander.server
|
|
44
58
|
```
|
|
45
59
|
|
|
46
|
-
## Configuration
|
|
60
|
+
## MCP Client Configuration
|
|
61
|
+
|
|
62
|
+
### Global npm Install
|
|
63
|
+
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"mcpServers": {
|
|
67
|
+
"servercommander": {
|
|
68
|
+
"command": "ellmos-servercommander"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Source Checkout
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"mcpServers": {
|
|
79
|
+
"servercommander": {
|
|
80
|
+
"command": "python",
|
|
81
|
+
"args": ["-m", "servercommander.server"],
|
|
82
|
+
"env": {
|
|
83
|
+
"PYTHONPATH": "/absolute/path/to/ellmos-servercommander-mcp/src"
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Replace `/absolute/path/to/ellmos-servercommander-mcp` with your local checkout path.
|
|
91
|
+
|
|
92
|
+
## Server Configuration
|
|
47
93
|
|
|
48
94
|
Example: [config/servercommander.example.toml](config/servercommander.example.toml)
|
|
49
95
|
|
|
@@ -66,10 +112,10 @@ Secrets should be referenced through environment variables, for example `$MAIL_P
|
|
|
66
112
|
## Tools
|
|
67
113
|
|
|
68
114
|
- `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
|
|
115
|
+
- `sc_logs_analyze`: analyzes Apache/Nginx access logs from inline text or a local file, including status classes, bytes, referers, error paths, and suspicious request markers
|
|
116
|
+
- `sc_deploy`: creates a deployment plan with a local SHA256 manifest and profile diagnostics, but does not upload yet
|
|
117
|
+
- `sc_deploy_status`: shows configured deploy profiles, selected-profile diagnostics, and the current alpha history status
|
|
118
|
+
- `sc_mail_list`, `sc_mail_read`, `sc_mail_send`, `sc_mail_search`: safe alpha status responses with mail configuration diagnostics and no IMAP/SMTP connections
|
|
73
119
|
|
|
74
120
|
## Development
|
|
75
121
|
|
|
@@ -81,4 +127,4 @@ npm run smoke
|
|
|
81
127
|
npm pack --dry-run
|
|
82
128
|
```
|
|
83
129
|
|
|
84
|
-
Next useful step:
|
|
130
|
+
Next useful step: add explicitly configured execution adapters for SFTP and IMAP/SMTP, keep dry-run defaults, and extend log analysis with persisted reports.
|
package/README_de.md
CHANGED
|
@@ -8,33 +8,47 @@ Alpha-MCP-Server für Server-Operationen: Deployment-Dry-runs, Mail-Status, Acce
|
|
|
8
8
|
|
|
9
9
|
Englische Standard-README: [README.md](README.md)
|
|
10
10
|
|
|
11
|
+
*Teil der [ellmos-ai](https://github.com/ellmos-ai)-Familie.*
|
|
12
|
+
|
|
13
|
+
[](https://opensource.org/licenses/MIT)
|
|
14
|
+
[](https://www.npmjs.com/package/ellmos-servercommander-mcp)
|
|
15
|
+
[](https://www.python.org/)
|
|
16
|
+
[](https://nodejs.org/)
|
|
17
|
+
[](https://modelcontextprotocol.io/)
|
|
18
|
+
[](https://www.npmjs.com/package/ellmos-servercommander-mcp)
|
|
19
|
+
|
|
20
|
+
**Auffindbarkeit:** Veröffentlicht auf [npm](https://www.npmjs.com/package/ellmos-servercommander-mcp) als `ellmos-servercommander-mcp` und gepflegt in der Organisation [`ellmos-ai`](https://github.com/ellmos-ai).
|
|
21
|
+
|
|
11
22
|
## Status
|
|
12
23
|
|
|
13
24
|
- Transport: stdio über das Python-MCP-SDK
|
|
14
25
|
- Paketstatus: öffentliches Alpha-Paket unter `ellmos-ai`
|
|
15
|
-
- Aktiver Kern: MCP-Tool-Liste, MCP-Tool-Dispatch, Config-Lader,
|
|
16
|
-
- Sichere Alpha-Handler: `sc_deploy` erstellt lokale SHA256-Manifeste im Dry-run, `sc_mail_*`
|
|
26
|
+
- Aktiver Kern: MCP-Tool-Liste, MCP-Tool-Dispatch, Config-Lader, HTTP-Health-Checks, erweiterte Access-Log-Analyse
|
|
27
|
+
- Sichere Alpha-Handler: `sc_deploy` erstellt lokale SHA256-Manifeste und Konfigurationsdiagnosen im Dry-run, `sc_mail_*` meldet Mail-Konfigurationslücken ohne IMAP/SMTP-Aktionen
|
|
17
28
|
- i18n: lokalisierte MCP-Tool-Beschreibungen, Input-Schema-Feldbeschreibungen und Unknown-Tool-Fehler für `en`, `de`, `es`, `zh`, `ja`, `ru` mit Englisch-Fallback
|
|
18
29
|
|
|
19
30
|
## Installation
|
|
20
31
|
|
|
21
32
|
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
33
|
|
|
34
|
+
### Option 1: Installation per npm
|
|
35
|
+
|
|
23
36
|
```powershell
|
|
24
37
|
npm install -g ellmos-servercommander-mcp@alpha
|
|
25
38
|
ellmos-servercommander
|
|
26
39
|
```
|
|
27
40
|
|
|
28
|
-
|
|
41
|
+
### Option 2: Installation aus dem Quellcode
|
|
29
42
|
|
|
30
43
|
```powershell
|
|
31
|
-
|
|
44
|
+
git clone https://github.com/ellmos-ai/ellmos-servercommander-mcp.git
|
|
45
|
+
cd ellmos-servercommander-mcp
|
|
32
46
|
$env:PYTHONIOENCODING = "utf-8"
|
|
33
47
|
python -m pip install -e ".[dev]"
|
|
34
48
|
python -m pytest -q
|
|
35
49
|
```
|
|
36
50
|
|
|
37
|
-
Keine `.venv`
|
|
51
|
+
Keine `.venv` in cloud-synchronisierten Ordnern anlegen, wenn der Sync-Client Dateien sperrt. Falls eine isolierte Umgebung gebraucht wird, außerhalb dieses Ordners erstellen.
|
|
38
52
|
|
|
39
53
|
## Start Aus Dem Quellbaum
|
|
40
54
|
|
|
@@ -43,7 +57,39 @@ $env:PYTHONPATH = "src"
|
|
|
43
57
|
python -m servercommander.server
|
|
44
58
|
```
|
|
45
59
|
|
|
46
|
-
## Konfiguration
|
|
60
|
+
## MCP-Client-Konfiguration
|
|
61
|
+
|
|
62
|
+
### Globale npm-Installation
|
|
63
|
+
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"mcpServers": {
|
|
67
|
+
"servercommander": {
|
|
68
|
+
"command": "ellmos-servercommander"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Quellcode-Checkout
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"mcpServers": {
|
|
79
|
+
"servercommander": {
|
|
80
|
+
"command": "python",
|
|
81
|
+
"args": ["-m", "servercommander.server"],
|
|
82
|
+
"env": {
|
|
83
|
+
"PYTHONPATH": "/absolute/path/to/ellmos-servercommander-mcp/src"
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
`/absolute/path/to/ellmos-servercommander-mcp` durch den eigenen lokalen Checkout-Pfad ersetzen.
|
|
91
|
+
|
|
92
|
+
## Server-Konfiguration
|
|
47
93
|
|
|
48
94
|
Beispiel: [config/servercommander.example.toml](config/servercommander.example.toml)
|
|
49
95
|
|
|
@@ -66,10 +112,10 @@ Secrets sollen als Umgebungsvariablen referenziert werden, zum Beispiel `$MAIL_P
|
|
|
66
112
|
## Tools
|
|
67
113
|
|
|
68
114
|
- `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
|
|
115
|
+
- `sc_logs_analyze`: analysiert Apache-/Nginx-Access-Logs aus Text oder Datei, inklusive Statusklassen, Bytes, Referern, Fehlerpfaden und verdächtigen Request-Markern
|
|
116
|
+
- `sc_deploy`: erstellt einen Deployment-Plan mit lokalem SHA256-Manifest und Profildiagnose, führt aber noch keinen Upload aus
|
|
117
|
+
- `sc_deploy_status`: zeigt konfigurierte Deploy-Profile, ausgewählte Profildiagnosen und den aktuellen Alpha-History-Status
|
|
118
|
+
- `sc_mail_list`, `sc_mail_read`, `sc_mail_send`, `sc_mail_search`: sichere Alpha-Statusantworten mit Mail-Konfigurationsdiagnosen und ohne IMAP/SMTP-Verbindung
|
|
73
119
|
|
|
74
120
|
## Entwicklung
|
|
75
121
|
|
|
@@ -81,4 +127,4 @@ npm run smoke
|
|
|
81
127
|
npm pack --dry-run
|
|
82
128
|
```
|
|
83
129
|
|
|
84
|
-
Der nächste sinnvolle Schritt ist
|
|
130
|
+
Der nächste sinnvolle Schritt ist, explizit konfigurierte Ausführungsadapter für SFTP und IMAP/SMTP zu ergänzen, Dry-run als Standard beizubehalten und Log-Analysen um persistierte Reports zu erweitern.
|
package/package.json
CHANGED
package/pyproject.toml
CHANGED
|
@@ -33,6 +33,7 @@ async def sc_deploy(
|
|
|
33
33
|
"local_path": local_path or profile_config.get("local_path"),
|
|
34
34
|
"remote_path": remote_path or profile_config.get("remote_path"),
|
|
35
35
|
"protocol": profile_config.get("protocol", "sftp"),
|
|
36
|
+
"port": profile_config.get("port", 22),
|
|
36
37
|
}
|
|
37
38
|
missing = [key for key in ("host", "user", "local_path", "remote_path") if not plan.get(key)]
|
|
38
39
|
manifest = _build_manifest(plan["local_path"]) if plan.get("local_path") else None
|
|
@@ -43,6 +44,7 @@ async def sc_deploy(
|
|
|
43
44
|
"missing": missing,
|
|
44
45
|
"plan": plan,
|
|
45
46
|
"manifest": manifest,
|
|
47
|
+
"diagnostics": _deploy_diagnostics(profile_config, plan, manifest),
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
|
|
@@ -58,6 +60,7 @@ async def sc_deploy_status(
|
|
|
58
60
|
"message": "Deployment history storage is not implemented yet.",
|
|
59
61
|
"profiles": profiles,
|
|
60
62
|
"selected_profile": selected,
|
|
63
|
+
"diagnostics": _deploy_diagnostics(selected or {}, selected or {}, None) if profile else None,
|
|
61
64
|
}
|
|
62
65
|
|
|
63
66
|
|
|
@@ -98,3 +101,24 @@ def _file_entry(path: Path, root: Path) -> dict[str, Any]:
|
|
|
98
101
|
"size": path.stat().st_size,
|
|
99
102
|
"sha256": digest.hexdigest(),
|
|
100
103
|
}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _deploy_diagnostics(profile_config: dict[str, Any], plan: dict[str, Any], manifest: dict[str, Any] | None) -> dict[str, Any]:
|
|
107
|
+
protocol = str(plan.get("protocol") or "sftp").lower()
|
|
108
|
+
auth_methods = []
|
|
109
|
+
if profile_config.get("key_path"):
|
|
110
|
+
auth_methods.append("key_path")
|
|
111
|
+
if profile_config.get("password"):
|
|
112
|
+
auth_methods.append("password")
|
|
113
|
+
if not auth_methods:
|
|
114
|
+
auth_methods.append("agent_or_prompt")
|
|
115
|
+
local_status = manifest.get("status") if manifest else "not_checked"
|
|
116
|
+
return {
|
|
117
|
+
"protocol_supported": protocol == "sftp",
|
|
118
|
+
"protocol": protocol,
|
|
119
|
+
"port": int(plan.get("port") or 22),
|
|
120
|
+
"auth_methods_configured": auth_methods,
|
|
121
|
+
"local_status": local_status,
|
|
122
|
+
"execution_enabled": False,
|
|
123
|
+
"next_step": "Review the dry-run plan and enable a future SFTP executor only after credential handling is finalized.",
|
|
124
|
+
}
|
|
@@ -18,6 +18,7 @@ LOG_PATTERN = re.compile(
|
|
|
18
18
|
)
|
|
19
19
|
|
|
20
20
|
BOT_MARKERS = ("bot", "crawler", "spider", "slurp", "bingpreview")
|
|
21
|
+
SUSPICIOUS_MARKERS = ("../", "%2e%2e", "/wp-admin", "/.env", "/phpmyadmin", "/admin", "/login")
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
async def sc_logs_analyze(
|
|
@@ -36,8 +37,13 @@ async def sc_logs_analyze(
|
|
|
36
37
|
status_classes: Counter[str] = Counter()
|
|
37
38
|
method_counts: Counter[str] = Counter()
|
|
38
39
|
path_counts: Counter[str] = Counter()
|
|
40
|
+
error_path_counts: Counter[str] = Counter()
|
|
39
41
|
agent_counts: Counter[str] = Counter()
|
|
42
|
+
referer_counts: Counter[str] = Counter()
|
|
43
|
+
hosts: set[str] = set()
|
|
44
|
+
total_bytes = 0
|
|
40
45
|
bot_requests = 0
|
|
46
|
+
suspicious_requests = 0
|
|
41
47
|
parsed_lines = 0
|
|
42
48
|
|
|
43
49
|
for line in lines:
|
|
@@ -45,28 +51,49 @@ async def sc_logs_analyze(
|
|
|
45
51
|
if not match:
|
|
46
52
|
continue
|
|
47
53
|
parsed_lines += 1
|
|
54
|
+
hosts.add(match.group("host"))
|
|
48
55
|
status = match.group("status")
|
|
49
56
|
status_counts[status] += 1
|
|
50
57
|
status_classes[f"{status[0]}xx"] += 1
|
|
51
58
|
method_counts[match.group("method")] += 1
|
|
52
|
-
|
|
59
|
+
path = match.group("path")
|
|
60
|
+
path_counts[path] += 1
|
|
61
|
+
if int(status) >= 400:
|
|
62
|
+
error_path_counts[path] += 1
|
|
63
|
+
size = match.group("size")
|
|
64
|
+
if size.isdigit():
|
|
65
|
+
total_bytes += int(size)
|
|
66
|
+
referer = match.group("referer") or ""
|
|
67
|
+
if referer and referer != "-":
|
|
68
|
+
referer_counts[referer] += 1
|
|
53
69
|
agent = match.group("agent") or ""
|
|
54
70
|
if agent:
|
|
55
71
|
agent_counts[agent] += 1
|
|
56
72
|
if any(marker in agent.lower() for marker in BOT_MARKERS):
|
|
57
73
|
bot_requests += 1
|
|
74
|
+
if any(marker in path.lower() for marker in SUSPICIOUS_MARKERS):
|
|
75
|
+
suspicious_requests += 1
|
|
76
|
+
|
|
77
|
+
error_count = sum(count for status, count in status_counts.items() if int(status) >= 400)
|
|
78
|
+
error_rate = round(error_count / parsed_lines, 4) if parsed_lines else 0.0
|
|
58
79
|
|
|
59
80
|
return {
|
|
60
81
|
"status": "ok",
|
|
61
82
|
"total_lines": len(lines),
|
|
62
83
|
"parsed_lines": parsed_lines,
|
|
63
84
|
"unparsed_lines": len(lines) - parsed_lines,
|
|
85
|
+
"unique_hosts": len(hosts),
|
|
86
|
+
"total_bytes": total_bytes,
|
|
87
|
+
"error_rate": error_rate,
|
|
64
88
|
"status_counts": dict(status_counts),
|
|
65
89
|
"status_classes": dict(status_classes),
|
|
66
90
|
"method_counts": dict(method_counts),
|
|
67
91
|
"top_paths": path_counts.most_common(int(top_paths)),
|
|
92
|
+
"top_error_paths": error_path_counts.most_common(int(top_paths)),
|
|
93
|
+
"top_referers": referer_counts.most_common(10),
|
|
68
94
|
"top_agents": agent_counts.most_common(10),
|
|
69
95
|
"bot_requests": bot_requests,
|
|
96
|
+
"suspicious_requests": suspicious_requests,
|
|
70
97
|
}
|
|
71
98
|
|
|
72
99
|
|
|
@@ -40,11 +40,27 @@ def _mail_alpha_response(config: ServerCommanderConfig, action: str, request: di
|
|
|
40
40
|
mail = config.mail
|
|
41
41
|
username = resolve_env_value(mail.get("username", ""))
|
|
42
42
|
password = resolve_env_value(mail.get("password", ""))
|
|
43
|
-
|
|
43
|
+
checks = {
|
|
44
|
+
"imap_host": bool(mail.get("imap_host")),
|
|
45
|
+
"smtp_host": bool(mail.get("smtp_host")),
|
|
46
|
+
"username": bool(username),
|
|
47
|
+
"password": bool(password),
|
|
48
|
+
}
|
|
49
|
+
configured = all(checks.values())
|
|
50
|
+
missing = [key for key, ok in checks.items() if not ok]
|
|
44
51
|
return {
|
|
45
52
|
"status": "not_implemented",
|
|
46
53
|
"action": action,
|
|
47
54
|
"configured": configured,
|
|
55
|
+
"missing": missing,
|
|
56
|
+
"checks": checks,
|
|
57
|
+
"capabilities": {
|
|
58
|
+
"list": False,
|
|
59
|
+
"read": False,
|
|
60
|
+
"send": False,
|
|
61
|
+
"search": False,
|
|
62
|
+
"config_diagnostics": True,
|
|
63
|
+
},
|
|
48
64
|
"request": request,
|
|
49
65
|
"message": "IMAP/SMTP execution is not implemented in the alpha server.",
|
|
50
66
|
}
|