arch-ops-server 3.1.0__tar.gz → 3.2.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.
Files changed (18) hide show
  1. {arch_ops_server-3.1.0 → arch_ops_server-3.2.0}/PKG-INFO +27 -7
  2. {arch_ops_server-3.1.0 → arch_ops_server-3.2.0}/README.md +26 -6
  3. {arch_ops_server-3.1.0 → arch_ops_server-3.2.0}/pyproject.toml +1 -1
  4. {arch_ops_server-3.1.0 → arch_ops_server-3.2.0}/src/arch_ops_server/__init__.py +3 -1
  5. {arch_ops_server-3.1.0 → arch_ops_server-3.2.0}/src/arch_ops_server/server.py +114 -41
  6. arch_ops_server-3.2.0/src/arch_ops_server/system_health_check.py +189 -0
  7. {arch_ops_server-3.1.0 → arch_ops_server-3.2.0}/src/arch_ops_server/tool_metadata.py +19 -0
  8. {arch_ops_server-3.1.0 → arch_ops_server-3.2.0}/src/arch_ops_server/aur.py +0 -0
  9. {arch_ops_server-3.1.0 → arch_ops_server-3.2.0}/src/arch_ops_server/config.py +0 -0
  10. {arch_ops_server-3.1.0 → arch_ops_server-3.2.0}/src/arch_ops_server/http_server.py +0 -0
  11. {arch_ops_server-3.1.0 → arch_ops_server-3.2.0}/src/arch_ops_server/logs.py +0 -0
  12. {arch_ops_server-3.1.0 → arch_ops_server-3.2.0}/src/arch_ops_server/mirrors.py +0 -0
  13. {arch_ops_server-3.1.0 → arch_ops_server-3.2.0}/src/arch_ops_server/news.py +0 -0
  14. {arch_ops_server-3.1.0 → arch_ops_server-3.2.0}/src/arch_ops_server/pacman.py +0 -0
  15. {arch_ops_server-3.1.0 → arch_ops_server-3.2.0}/src/arch_ops_server/py.typed +0 -0
  16. {arch_ops_server-3.1.0 → arch_ops_server-3.2.0}/src/arch_ops_server/system.py +0 -0
  17. {arch_ops_server-3.1.0 → arch_ops_server-3.2.0}/src/arch_ops_server/utils.py +0 -0
  18. {arch_ops_server-3.1.0 → arch_ops_server-3.2.0}/src/arch_ops_server/wiki.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: arch-ops-server
3
- Version: 3.1.0
3
+ Version: 3.2.0
4
4
  Summary: MCP server bridging AI assistants with Arch Linux ecosystem (Wiki, AUR, official repos)
5
5
  Keywords: arch-linux,mcp,model-context-protocol,aur,pacman,wiki,ai-assistant
6
6
  Author: Nihal
@@ -52,17 +52,18 @@ Leverage AI to get output for digestible, structured results that are ready for
52
52
 
53
53
  ## Sneak Peak into what's available
54
54
 
55
- <details open>
56
- <summary>Claude Desktop (no terminal)</summary>
55
+ <details>
56
+
57
+ <summary>Using VS Code Sonnet 3.5 for Safe Installation from AUR</summary>
57
58
 
58
- ![Claude Desktop Demo](assets/claudedesktop_signalcli.gif)
59
+ ![VS Code Demo](assets/vscode_notesnook.gif)
59
60
 
60
61
  </details>
61
62
 
62
63
  <details>
63
- <summary>VS Code (with terminal)</summary>
64
+ <summary> Asking Claude Code Sonnet 4.5 for fedora equivalent command </summary>
64
65
 
65
- ![VS Code Demo](assets/vscode_notesnook.gif)
66
+ ![Equivalent Command Demo](assets/equivalent-commands.gif)
66
67
 
67
68
  </details>
68
69
 
@@ -71,11 +72,13 @@ Leverage AI to get output for digestible, structured results that are ready for
71
72
  Direct access to Arch ecosystem data via custom URI schemes:
72
73
 
73
74
  #### Documentation & Search
75
+
74
76
  | URI Scheme | Example | Returns |
75
77
  |------------|---------|---------|
76
78
  | `archwiki://` | `archwiki://Installation_guide` | Markdown-formatted Wiki page |
77
79
 
78
80
  #### Package Information
81
+
79
82
  | URI Scheme | Example | Returns |
80
83
  |------------|---------|---------|
81
84
  | `archrepo://` | `archrepo://vim` | Official repository package details |
@@ -83,6 +86,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
83
86
  | `aur://*/pkgbuild` | `aur://yay/pkgbuild` | Raw PKGBUILD with safety analysis |
84
87
 
85
88
  #### System Packages (Arch only)
89
+
86
90
  | URI Scheme | Example | Returns |
87
91
  |------------|---------|---------|
88
92
  | `pacman://installed` | `pacman://installed` | System installed packages list |
@@ -93,6 +97,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
93
97
  | `pacman://database/freshness` | `pacman://database/freshness` | Package database sync status |
94
98
 
95
99
  #### System Monitoring & Logs
100
+
96
101
  | URI Scheme | Example | Returns |
97
102
  |------------|---------|---------|
98
103
  | `system://info` | `system://info` | System information (kernel, memory, uptime) |
@@ -103,6 +108,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
103
108
  | `pacman://log/failed` | `pacman://log/failed` | Failed package transactions |
104
109
 
105
110
  #### News & Updates
111
+
106
112
  | URI Scheme | Example | Returns |
107
113
  |------------|---------|---------|
108
114
  | `archnews://latest` | `archnews://latest` | Latest Arch Linux news |
@@ -110,6 +116,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
110
116
  | `archnews://since-update` | `archnews://since-update` | News since last system update |
111
117
 
112
118
  #### Configuration
119
+
113
120
  | URI Scheme | Example | Returns |
114
121
  |------------|---------|---------|
115
122
  | `config://pacman` | `config://pacman` | Parsed pacman.conf configuration |
@@ -120,6 +127,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
120
127
  ### Tools (Executable Functions)
121
128
 
122
129
  #### Package Search & Information
130
+
123
131
  | Tool | Description | Platform |
124
132
  |------|-------------|----------|
125
133
  | `search_archwiki` | Query Arch Wiki with ranked results | Any |
@@ -127,6 +135,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
127
135
  | `get_official_package_info` | Get official package details (hybrid local/remote) | Any |
128
136
 
129
137
  #### Package Lifecycle Management
138
+
130
139
  | Tool | Description | Platform |
131
140
  |------|-------------|----------|
132
141
  | `check_updates_dry_run` | Check for available updates | Arch only |
@@ -135,6 +144,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
135
144
  | `remove_packages_batch` | Remove multiple packages efficiently | Arch only |
136
145
 
137
146
  #### Package Analysis & Maintenance
147
+
138
148
  | Tool | Description | Platform |
139
149
  |------|-------------|----------|
140
150
  | `list_orphan_packages` | Find orphaned packages | Arch only |
@@ -145,6 +155,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
145
155
  | `mark_as_dependency` | Allow package to be orphaned | Arch only |
146
156
 
147
157
  #### Package Organization
158
+
148
159
  | Tool | Description | Platform |
149
160
  |------|-------------|----------|
150
161
  | `find_package_owner` | Find which package owns a file | Arch only |
@@ -154,6 +165,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
154
165
  | `list_group_packages` | Show packages in specific group | Arch only |
155
166
 
156
167
  #### System Monitoring & Diagnostics
168
+
157
169
  | Tool | Description | Platform |
158
170
  |------|-------------|----------|
159
171
  | `get_system_info` | System info (kernel, memory, uptime) | Any |
@@ -164,6 +176,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
164
176
  | `check_database_freshness` | Check package database sync status | Arch only |
165
177
 
166
178
  #### Transaction History & Logs
179
+
167
180
  | Tool | Description | Platform |
168
181
  |------|-------------|----------|
169
182
  | `get_transaction_history` | Recent package transactions (install/upgrade/remove) | Arch only |
@@ -172,6 +185,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
172
185
  | `get_database_sync_history` | Database sync events | Arch only |
173
186
 
174
187
  #### News & Safety Checks
188
+
175
189
  | Tool | Description | Platform |
176
190
  |------|-------------|----------|
177
191
  | `get_latest_news` | Fetch Arch Linux news from RSS | Any |
@@ -179,6 +193,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
179
193
  | `get_news_since_last_update` | News posted since last system update | Arch only |
180
194
 
181
195
  #### Mirror Management
196
+
182
197
  | Tool | Description | Platform |
183
198
  |------|-------------|----------|
184
199
  | `list_active_mirrors` | Show configured mirrors | Arch only |
@@ -187,6 +202,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
187
202
  | `check_mirrorlist_health` | Verify mirror configuration | Arch only |
188
203
 
189
204
  #### Configuration Management
205
+
190
206
  | Tool | Description | Platform |
191
207
  |------|-------------|----------|
192
208
  | `analyze_pacman_conf` | Parse pacman.conf settings | Arch only |
@@ -195,6 +211,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
195
211
  | `get_parallel_downloads_setting` | Get parallel download config | Arch only |
196
212
 
197
213
  #### Security Analysis
214
+
198
215
  | Tool | Description | Platform |
199
216
  |------|-------------|----------|
200
217
  | `analyze_pkgbuild_safety` | Comprehensive PKGBUILD analysis (50+ red flags) | Any |
@@ -214,6 +231,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
214
231
  ## Installation
215
232
 
216
233
  ### Prerequisites
234
+
217
235
  - Python 3.11+
218
236
  - [uv](https://github.com/astral-sh/uv) (recommended) or pip
219
237
 
@@ -222,6 +240,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
222
240
  ```bash
223
241
  uvx arch-ops-server
224
242
  ```
243
+
225
244
  ---
226
245
 
227
246
  ## Configuration
@@ -254,4 +273,5 @@ This project is dual-licensed under your choice of:
254
273
 
255
274
  You may use this software under the terms of either license. When redistributing or modifying this software, you may choose which license to apply.
256
275
 
257
- By contributing to this project, you agree that your contributions will be licensed under both licenses.
276
+ By contributing to this project, you agree that your contributions will be licensed under both licenses.
277
+
@@ -16,17 +16,18 @@ Leverage AI to get output for digestible, structured results that are ready for
16
16
 
17
17
  ## Sneak Peak into what's available
18
18
 
19
- <details open>
20
- <summary>Claude Desktop (no terminal)</summary>
19
+ <details>
20
+
21
+ <summary>Using VS Code Sonnet 3.5 for Safe Installation from AUR</summary>
21
22
 
22
- ![Claude Desktop Demo](assets/claudedesktop_signalcli.gif)
23
+ ![VS Code Demo](assets/vscode_notesnook.gif)
23
24
 
24
25
  </details>
25
26
 
26
27
  <details>
27
- <summary>VS Code (with terminal)</summary>
28
+ <summary> Asking Claude Code Sonnet 4.5 for fedora equivalent command </summary>
28
29
 
29
- ![VS Code Demo](assets/vscode_notesnook.gif)
30
+ ![Equivalent Command Demo](assets/equivalent-commands.gif)
30
31
 
31
32
  </details>
32
33
 
@@ -35,11 +36,13 @@ Leverage AI to get output for digestible, structured results that are ready for
35
36
  Direct access to Arch ecosystem data via custom URI schemes:
36
37
 
37
38
  #### Documentation & Search
39
+
38
40
  | URI Scheme | Example | Returns |
39
41
  |------------|---------|---------|
40
42
  | `archwiki://` | `archwiki://Installation_guide` | Markdown-formatted Wiki page |
41
43
 
42
44
  #### Package Information
45
+
43
46
  | URI Scheme | Example | Returns |
44
47
  |------------|---------|---------|
45
48
  | `archrepo://` | `archrepo://vim` | Official repository package details |
@@ -47,6 +50,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
47
50
  | `aur://*/pkgbuild` | `aur://yay/pkgbuild` | Raw PKGBUILD with safety analysis |
48
51
 
49
52
  #### System Packages (Arch only)
53
+
50
54
  | URI Scheme | Example | Returns |
51
55
  |------------|---------|---------|
52
56
  | `pacman://installed` | `pacman://installed` | System installed packages list |
@@ -57,6 +61,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
57
61
  | `pacman://database/freshness` | `pacman://database/freshness` | Package database sync status |
58
62
 
59
63
  #### System Monitoring & Logs
64
+
60
65
  | URI Scheme | Example | Returns |
61
66
  |------------|---------|---------|
62
67
  | `system://info` | `system://info` | System information (kernel, memory, uptime) |
@@ -67,6 +72,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
67
72
  | `pacman://log/failed` | `pacman://log/failed` | Failed package transactions |
68
73
 
69
74
  #### News & Updates
75
+
70
76
  | URI Scheme | Example | Returns |
71
77
  |------------|---------|---------|
72
78
  | `archnews://latest` | `archnews://latest` | Latest Arch Linux news |
@@ -74,6 +80,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
74
80
  | `archnews://since-update` | `archnews://since-update` | News since last system update |
75
81
 
76
82
  #### Configuration
83
+
77
84
  | URI Scheme | Example | Returns |
78
85
  |------------|---------|---------|
79
86
  | `config://pacman` | `config://pacman` | Parsed pacman.conf configuration |
@@ -84,6 +91,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
84
91
  ### Tools (Executable Functions)
85
92
 
86
93
  #### Package Search & Information
94
+
87
95
  | Tool | Description | Platform |
88
96
  |------|-------------|----------|
89
97
  | `search_archwiki` | Query Arch Wiki with ranked results | Any |
@@ -91,6 +99,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
91
99
  | `get_official_package_info` | Get official package details (hybrid local/remote) | Any |
92
100
 
93
101
  #### Package Lifecycle Management
102
+
94
103
  | Tool | Description | Platform |
95
104
  |------|-------------|----------|
96
105
  | `check_updates_dry_run` | Check for available updates | Arch only |
@@ -99,6 +108,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
99
108
  | `remove_packages_batch` | Remove multiple packages efficiently | Arch only |
100
109
 
101
110
  #### Package Analysis & Maintenance
111
+
102
112
  | Tool | Description | Platform |
103
113
  |------|-------------|----------|
104
114
  | `list_orphan_packages` | Find orphaned packages | Arch only |
@@ -109,6 +119,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
109
119
  | `mark_as_dependency` | Allow package to be orphaned | Arch only |
110
120
 
111
121
  #### Package Organization
122
+
112
123
  | Tool | Description | Platform |
113
124
  |------|-------------|----------|
114
125
  | `find_package_owner` | Find which package owns a file | Arch only |
@@ -118,6 +129,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
118
129
  | `list_group_packages` | Show packages in specific group | Arch only |
119
130
 
120
131
  #### System Monitoring & Diagnostics
132
+
121
133
  | Tool | Description | Platform |
122
134
  |------|-------------|----------|
123
135
  | `get_system_info` | System info (kernel, memory, uptime) | Any |
@@ -128,6 +140,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
128
140
  | `check_database_freshness` | Check package database sync status | Arch only |
129
141
 
130
142
  #### Transaction History & Logs
143
+
131
144
  | Tool | Description | Platform |
132
145
  |------|-------------|----------|
133
146
  | `get_transaction_history` | Recent package transactions (install/upgrade/remove) | Arch only |
@@ -136,6 +149,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
136
149
  | `get_database_sync_history` | Database sync events | Arch only |
137
150
 
138
151
  #### News & Safety Checks
152
+
139
153
  | Tool | Description | Platform |
140
154
  |------|-------------|----------|
141
155
  | `get_latest_news` | Fetch Arch Linux news from RSS | Any |
@@ -143,6 +157,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
143
157
  | `get_news_since_last_update` | News posted since last system update | Arch only |
144
158
 
145
159
  #### Mirror Management
160
+
146
161
  | Tool | Description | Platform |
147
162
  |------|-------------|----------|
148
163
  | `list_active_mirrors` | Show configured mirrors | Arch only |
@@ -151,6 +166,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
151
166
  | `check_mirrorlist_health` | Verify mirror configuration | Arch only |
152
167
 
153
168
  #### Configuration Management
169
+
154
170
  | Tool | Description | Platform |
155
171
  |------|-------------|----------|
156
172
  | `analyze_pacman_conf` | Parse pacman.conf settings | Arch only |
@@ -159,6 +175,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
159
175
  | `get_parallel_downloads_setting` | Get parallel download config | Arch only |
160
176
 
161
177
  #### Security Analysis
178
+
162
179
  | Tool | Description | Platform |
163
180
  |------|-------------|----------|
164
181
  | `analyze_pkgbuild_safety` | Comprehensive PKGBUILD analysis (50+ red flags) | Any |
@@ -178,6 +195,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
178
195
  ## Installation
179
196
 
180
197
  ### Prerequisites
198
+
181
199
  - Python 3.11+
182
200
  - [uv](https://github.com/astral-sh/uv) (recommended) or pip
183
201
 
@@ -186,6 +204,7 @@ Direct access to Arch ecosystem data via custom URI schemes:
186
204
  ```bash
187
205
  uvx arch-ops-server
188
206
  ```
207
+
189
208
  ---
190
209
 
191
210
  ## Configuration
@@ -218,4 +237,5 @@ This project is dual-licensed under your choice of:
218
237
 
219
238
  You may use this software under the terms of either license. When redistributing or modifying this software, you may choose which license to apply.
220
239
 
221
- By contributing to this project, you agree that your contributions will be licensed under both licenses.
240
+ By contributing to this project, you agree that your contributions will be licensed under both licenses.
241
+
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "arch-ops-server"
3
- version = "3.1.0"
3
+ version = "3.2.0"
4
4
  description = "MCP server bridging AI assistants with Arch Linux ecosystem (Wiki, AUR, official repos)"
5
5
  readme = {file = "README.md", content-type = "text/markdown"}
6
6
  license = { text = "GPL-3.0-only OR MIT" }
@@ -6,7 +6,7 @@ A Model Context Protocol server that bridges AI assistants with the Arch Linux
6
6
  ecosystem, providing access to the Arch Wiki, AUR, and official repositories.
7
7
  """
8
8
 
9
- __version__ = "3.1.0"
9
+ __version__ = "3.2.0"
10
10
 
11
11
  from .wiki import search_wiki, get_wiki_page, get_wiki_page_as_text
12
12
  from .aur import (
@@ -43,6 +43,7 @@ from .system import (
43
43
  check_failed_services,
44
44
  get_boot_logs
45
45
  )
46
+ from .system_health_check import run_system_health_check
46
47
  from .news import (
47
48
  get_latest_news,
48
49
  check_critical_news,
@@ -147,6 +148,7 @@ __all__ = [
147
148
  "get_pacman_cache_stats",
148
149
  "check_failed_services",
149
150
  "get_boot_logs",
151
+ "run_system_health_check",
150
152
  # News
151
153
  "get_latest_news",
152
154
  "check_critical_news",
@@ -15,6 +15,7 @@ from mcp.server import Server
15
15
  from mcp.types import (
16
16
  Resource,
17
17
  Tool,
18
+ ToolAnnotations,
18
19
  TextContent,
19
20
  ImageContent,
20
21
  EmbeddedResource,
@@ -76,6 +77,8 @@ from . import (
76
77
  analyze_makepkg_conf,
77
78
  check_ignored_packages,
78
79
  get_parallel_downloads_setting,
80
+ # System health check
81
+ run_system_health_check,
79
82
  # Utils
80
83
  IS_ARCH,
81
84
  run_command,
@@ -302,6 +305,13 @@ async def list_resources() -> list[Resource]:
302
305
  mimeType="application/json",
303
306
  description="Check when package databases were last synchronized"
304
307
  ),
308
+ # System health resources
309
+ Resource(
310
+ uri="system://health",
311
+ name="System - Health Check",
312
+ mimeType="application/json",
313
+ description="Comprehensive system health check report"
314
+ ),
305
315
  ]
306
316
 
307
317
 
@@ -482,6 +492,11 @@ async def read_resource(uri: str) -> str:
482
492
  else:
483
493
  raise ValueError(result.get("error", "Failed to get boot logs"))
484
494
 
495
+ elif resource_path == "health":
496
+ # Get system health check
497
+ result = await run_system_health_check()
498
+ return json.dumps(result, indent=2)
499
+
485
500
  else:
486
501
  raise ValueError(f"Unsupported system resource: {resource_path}")
487
502
 
@@ -579,7 +594,8 @@ async def list_tools() -> list[Tool]:
579
594
  }
580
595
  },
581
596
  "required": ["query"]
582
- }
597
+ },
598
+ annotations=ToolAnnotations(readOnlyHint=True)
583
599
  ),
584
600
 
585
601
  # AUR tools
@@ -606,7 +622,8 @@ async def list_tools() -> list[Tool]:
606
622
  }
607
623
  },
608
624
  "required": ["query"]
609
- }
625
+ },
626
+ annotations=ToolAnnotations(readOnlyHint=True)
610
627
  ),
611
628
 
612
629
  Tool(
@@ -621,7 +638,8 @@ async def list_tools() -> list[Tool]:
621
638
  }
622
639
  },
623
640
  "required": ["package_name"]
624
- }
641
+ },
642
+ annotations=ToolAnnotations(readOnlyHint=True)
625
643
  ),
626
644
 
627
645
  Tool(
@@ -630,7 +648,8 @@ async def list_tools() -> list[Tool]:
630
648
  inputSchema={
631
649
  "type": "object",
632
650
  "properties": {}
633
- }
651
+ },
652
+ annotations=ToolAnnotations(readOnlyHint=True)
634
653
  ),
635
654
 
636
655
  Tool(
@@ -645,7 +664,8 @@ async def list_tools() -> list[Tool]:
645
664
  }
646
665
  },
647
666
  "required": ["package_name"]
648
- }
667
+ },
668
+ annotations=ToolAnnotations(destructiveHint=True)
649
669
  ),
650
670
 
651
671
  Tool(
@@ -660,7 +680,8 @@ async def list_tools() -> list[Tool]:
660
680
  }
661
681
  },
662
682
  "required": ["pkgbuild_content"]
663
- }
683
+ },
684
+ annotations=ToolAnnotations(readOnlyHint=True)
664
685
  ),
665
686
 
666
687
  Tool(
@@ -675,7 +696,8 @@ async def list_tools() -> list[Tool]:
675
696
  }
676
697
  },
677
698
  "required": ["package_info"]
678
- }
699
+ },
700
+ annotations=ToolAnnotations(readOnlyHint=True)
679
701
  ),
680
702
 
681
703
  # Package Removal Tools
@@ -701,7 +723,8 @@ async def list_tools() -> list[Tool]:
701
723
  }
702
724
  },
703
725
  "required": ["package_name"]
704
- }
726
+ },
727
+ annotations=ToolAnnotations(destructiveHint=True)
705
728
  ),
706
729
 
707
730
  Tool(
@@ -722,7 +745,8 @@ async def list_tools() -> list[Tool]:
722
745
  }
723
746
  },
724
747
  "required": ["package_names"]
725
- }
748
+ },
749
+ annotations=ToolAnnotations(destructiveHint=True)
726
750
  ),
727
751
 
728
752
  # Orphan Package Management
@@ -732,7 +756,8 @@ async def list_tools() -> list[Tool]:
732
756
  inputSchema={
733
757
  "type": "object",
734
758
  "properties": {}
735
- }
759
+ },
760
+ annotations=ToolAnnotations(readOnlyHint=True)
736
761
  ),
737
762
 
738
763
  Tool(
@@ -753,7 +778,8 @@ async def list_tools() -> list[Tool]:
753
778
  }
754
779
  },
755
780
  "required": []
756
- }
781
+ },
782
+ annotations=ToolAnnotations(destructiveHint=True)
757
783
  ),
758
784
 
759
785
  # Package Ownership Tools
@@ -769,7 +795,8 @@ async def list_tools() -> list[Tool]:
769
795
  }
770
796
  },
771
797
  "required": ["file_path"]
772
- }
798
+ },
799
+ annotations=ToolAnnotations(readOnlyHint=True)
773
800
  ),
774
801
 
775
802
  Tool(
@@ -788,7 +815,8 @@ async def list_tools() -> list[Tool]:
788
815
  }
789
816
  },
790
817
  "required": ["package_name"]
791
- }
818
+ },
819
+ annotations=ToolAnnotations(readOnlyHint=True)
792
820
  ),
793
821
 
794
822
  Tool(
@@ -803,7 +831,8 @@ async def list_tools() -> list[Tool]:
803
831
  }
804
832
  },
805
833
  "required": ["filename_pattern"]
806
- }
834
+ },
835
+ annotations=ToolAnnotations(readOnlyHint=True)
807
836
  ),
808
837
 
809
838
  # Package Verification
@@ -824,7 +853,8 @@ async def list_tools() -> list[Tool]:
824
853
  }
825
854
  },
826
855
  "required": ["package_name"]
827
- }
856
+ },
857
+ annotations=ToolAnnotations(readOnlyHint=True)
828
858
  ),
829
859
 
830
860
  # Package Groups
@@ -834,7 +864,8 @@ async def list_tools() -> list[Tool]:
834
864
  inputSchema={
835
865
  "type": "object",
836
866
  "properties": {}
837
- }
867
+ },
868
+ annotations=ToolAnnotations(readOnlyHint=True)
838
869
  ),
839
870
 
840
871
  Tool(
@@ -849,7 +880,8 @@ async def list_tools() -> list[Tool]:
849
880
  }
850
881
  },
851
882
  "required": ["group_name"]
852
- }
883
+ },
884
+ annotations=ToolAnnotations(readOnlyHint=True)
853
885
  ),
854
886
 
855
887
  # Install Reason Management
@@ -859,7 +891,8 @@ async def list_tools() -> list[Tool]:
859
891
  inputSchema={
860
892
  "type": "object",
861
893
  "properties": {}
862
- }
894
+ },
895
+ annotations=ToolAnnotations(readOnlyHint=True)
863
896
  ),
864
897
 
865
898
  Tool(
@@ -874,7 +907,8 @@ async def list_tools() -> list[Tool]:
874
907
  }
875
908
  },
876
909
  "required": ["package_name"]
877
- }
910
+ },
911
+ annotations=ToolAnnotations(destructiveHint=True)
878
912
  ),
879
913
 
880
914
  Tool(
@@ -889,7 +923,8 @@ async def list_tools() -> list[Tool]:
889
923
  }
890
924
  },
891
925
  "required": ["package_name"]
892
- }
926
+ },
927
+ annotations=ToolAnnotations(destructiveHint=True)
893
928
  ),
894
929
 
895
930
  # System Diagnostic Tools
@@ -899,7 +934,8 @@ async def list_tools() -> list[Tool]:
899
934
  inputSchema={
900
935
  "type": "object",
901
936
  "properties": {}
902
- }
937
+ },
938
+ annotations=ToolAnnotations(readOnlyHint=True)
903
939
  ),
904
940
 
905
941
  Tool(
@@ -908,7 +944,8 @@ async def list_tools() -> list[Tool]:
908
944
  inputSchema={
909
945
  "type": "object",
910
946
  "properties": {}
911
- }
947
+ },
948
+ annotations=ToolAnnotations(readOnlyHint=True)
912
949
  ),
913
950
 
914
951
  Tool(
@@ -917,7 +954,8 @@ async def list_tools() -> list[Tool]:
917
954
  inputSchema={
918
955
  "type": "object",
919
956
  "properties": {}
920
- }
957
+ },
958
+ annotations=ToolAnnotations(readOnlyHint=True)
921
959
  ),
922
960
 
923
961
  Tool(
@@ -926,7 +964,8 @@ async def list_tools() -> list[Tool]:
926
964
  inputSchema={
927
965
  "type": "object",
928
966
  "properties": {}
929
- }
967
+ },
968
+ annotations=ToolAnnotations(readOnlyHint=True)
930
969
  ),
931
970
 
932
971
  Tool(
@@ -942,7 +981,8 @@ async def list_tools() -> list[Tool]:
942
981
  }
943
982
  },
944
983
  "required": []
945
- }
984
+ },
985
+ annotations=ToolAnnotations(readOnlyHint=True)
946
986
  ),
947
987
 
948
988
  # News Tools
@@ -963,7 +1003,8 @@ async def list_tools() -> list[Tool]:
963
1003
  }
964
1004
  },
965
1005
  "required": []
966
- }
1006
+ },
1007
+ annotations=ToolAnnotations(readOnlyHint=True)
967
1008
  ),
968
1009
 
969
1010
  Tool(
@@ -979,7 +1020,8 @@ async def list_tools() -> list[Tool]:
979
1020
  }
980
1021
  },
981
1022
  "required": []
982
- }
1023
+ },
1024
+ annotations=ToolAnnotations(readOnlyHint=True)
983
1025
  ),
984
1026
 
985
1027
  Tool(
@@ -988,7 +1030,8 @@ async def list_tools() -> list[Tool]:
988
1030
  inputSchema={
989
1031
  "type": "object",
990
1032
  "properties": {}
991
- }
1033
+ },
1034
+ annotations=ToolAnnotations(readOnlyHint=True)
992
1035
  ),
993
1036
 
994
1037
  # Transaction Log Tools
@@ -1011,7 +1054,8 @@ async def list_tools() -> list[Tool]:
1011
1054
  }
1012
1055
  },
1013
1056
  "required": []
1014
- }
1057
+ },
1058
+ annotations=ToolAnnotations(readOnlyHint=True)
1015
1059
  ),
1016
1060
 
1017
1061
  Tool(
@@ -1026,7 +1070,8 @@ async def list_tools() -> list[Tool]:
1026
1070
  }
1027
1071
  },
1028
1072
  "required": ["package_name"]
1029
- }
1073
+ },
1074
+ annotations=ToolAnnotations(readOnlyHint=True)
1030
1075
  ),
1031
1076
 
1032
1077
  Tool(
@@ -1035,7 +1080,8 @@ async def list_tools() -> list[Tool]:
1035
1080
  inputSchema={
1036
1081
  "type": "object",
1037
1082
  "properties": {}
1038
- }
1083
+ },
1084
+ annotations=ToolAnnotations(readOnlyHint=True)
1039
1085
  ),
1040
1086
 
1041
1087
  Tool(
@@ -1051,7 +1097,8 @@ async def list_tools() -> list[Tool]:
1051
1097
  }
1052
1098
  },
1053
1099
  "required": []
1054
- }
1100
+ },
1101
+ annotations=ToolAnnotations(readOnlyHint=True)
1055
1102
  ),
1056
1103
 
1057
1104
  # Mirror Management Tools
@@ -1061,7 +1108,8 @@ async def list_tools() -> list[Tool]:
1061
1108
  inputSchema={
1062
1109
  "type": "object",
1063
1110
  "properties": {}
1064
- }
1111
+ },
1112
+ annotations=ToolAnnotations(readOnlyHint=True)
1065
1113
  ),
1066
1114
 
1067
1115
  Tool(
@@ -1076,7 +1124,8 @@ async def list_tools() -> list[Tool]:
1076
1124
  }
1077
1125
  },
1078
1126
  "required": []
1079
- }
1127
+ },
1128
+ annotations=ToolAnnotations(readOnlyHint=True)
1080
1129
  ),
1081
1130
 
1082
1131
  Tool(
@@ -1096,7 +1145,8 @@ async def list_tools() -> list[Tool]:
1096
1145
  }
1097
1146
  },
1098
1147
  "required": []
1099
- }
1148
+ },
1149
+ annotations=ToolAnnotations(readOnlyHint=True)
1100
1150
  ),
1101
1151
 
1102
1152
  Tool(
@@ -1105,7 +1155,8 @@ async def list_tools() -> list[Tool]:
1105
1155
  inputSchema={
1106
1156
  "type": "object",
1107
1157
  "properties": {}
1108
- }
1158
+ },
1159
+ annotations=ToolAnnotations(readOnlyHint=True)
1109
1160
  ),
1110
1161
 
1111
1162
  # Configuration Tools
@@ -1115,7 +1166,8 @@ async def list_tools() -> list[Tool]:
1115
1166
  inputSchema={
1116
1167
  "type": "object",
1117
1168
  "properties": {}
1118
- }
1169
+ },
1170
+ annotations=ToolAnnotations(readOnlyHint=True)
1119
1171
  ),
1120
1172
 
1121
1173
  Tool(
@@ -1124,7 +1176,8 @@ async def list_tools() -> list[Tool]:
1124
1176
  inputSchema={
1125
1177
  "type": "object",
1126
1178
  "properties": {}
1127
- }
1179
+ },
1180
+ annotations=ToolAnnotations(readOnlyHint=True)
1128
1181
  ),
1129
1182
 
1130
1183
  Tool(
@@ -1133,7 +1186,8 @@ async def list_tools() -> list[Tool]:
1133
1186
  inputSchema={
1134
1187
  "type": "object",
1135
1188
  "properties": {}
1136
- }
1189
+ },
1190
+ annotations=ToolAnnotations(readOnlyHint=True)
1137
1191
  ),
1138
1192
 
1139
1193
  Tool(
@@ -1142,7 +1196,8 @@ async def list_tools() -> list[Tool]:
1142
1196
  inputSchema={
1143
1197
  "type": "object",
1144
1198
  "properties": {}
1145
- }
1199
+ },
1200
+ annotations=ToolAnnotations(readOnlyHint=True)
1146
1201
  ),
1147
1202
 
1148
1203
  Tool(
@@ -1151,7 +1206,18 @@ async def list_tools() -> list[Tool]:
1151
1206
  inputSchema={
1152
1207
  "type": "object",
1153
1208
  "properties": {}
1154
- }
1209
+ },
1210
+ annotations=ToolAnnotations(readOnlyHint=True)
1211
+ ),
1212
+
1213
+ Tool(
1214
+ name="run_system_health_check",
1215
+ description="[MONITORING] Run a comprehensive system health check. Integrates multiple diagnostics to provide a complete overview of system status, including disk space, failed services, updates, orphan packages, and more. Only works on Arch Linux.",
1216
+ inputSchema={
1217
+ "type": "object",
1218
+ "properties": {}
1219
+ },
1220
+ annotations=ToolAnnotations(readOnlyHint=True)
1155
1221
  ),
1156
1222
  ]
1157
1223
 
@@ -1466,6 +1532,13 @@ async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent |
1466
1532
 
1467
1533
  result = await get_parallel_downloads_setting()
1468
1534
  return [TextContent(type="text", text=json.dumps(result, indent=2))]
1535
+
1536
+ elif name == "run_system_health_check":
1537
+ if not IS_ARCH:
1538
+ return [TextContent(type="text", text="Error: run_system_health_check only available on Arch Linux systems")]
1539
+
1540
+ result = await run_system_health_check()
1541
+ return [TextContent(type="text", text=json.dumps(result, indent=2))]
1469
1542
 
1470
1543
  elif name == "check_database_freshness":
1471
1544
  if not IS_ARCH:
@@ -0,0 +1,189 @@
1
+ # SPDX-License-Identifier: GPL-3.0-only OR MIT
2
+ """
3
+ System health check module.
4
+ Provides a comprehensive system health check by integrating multiple system diagnostics.
5
+ """
6
+
7
+ import logging
8
+ from typing import Dict, Any
9
+
10
+ from .utils import IS_ARCH
11
+ from . import (
12
+ get_system_info,
13
+ check_disk_space,
14
+ check_failed_services,
15
+ get_pacman_cache_stats,
16
+ check_updates_dry_run,
17
+ check_critical_news,
18
+ list_orphan_packages,
19
+ check_database_freshness,
20
+ check_mirrorlist_health
21
+ )
22
+
23
+ logger = logging.getLogger(__name__)
24
+
25
+
26
+ async def run_system_health_check() -> Dict[str, Any]:
27
+ """
28
+ Run a comprehensive system health check.
29
+
30
+ This function integrates multiple system diagnostics to provide a complete
31
+ overview of the system's health status in a single call.
32
+
33
+ Returns:
34
+ Dict with comprehensive health check results
35
+ """
36
+ logger.info("Starting comprehensive system health check")
37
+
38
+ health_report = {
39
+ "status": "success",
40
+ "system_info": {},
41
+ "disk_space": {},
42
+ "services": {},
43
+ "pacman_cache": {},
44
+ "updates": {},
45
+ "news": {},
46
+ "orphans": {},
47
+ "database": {},
48
+ "mirrors": {},
49
+ "issues": [],
50
+ "suggestions": []
51
+ }
52
+
53
+ try:
54
+ # System information
55
+ logger.info("Checking system information")
56
+ system_info = await get_system_info()
57
+ health_report["system_info"] = system_info
58
+
59
+ # Disk space check
60
+ logger.info("Checking disk space")
61
+ disk_space = await check_disk_space()
62
+ health_report["disk_space"] = disk_space
63
+
64
+ # Check for low disk space
65
+ if disk_space.get("status") == "success":
66
+ for partition in disk_space.get("data", []):
67
+ if partition.get("used_percent", 0) > 90:
68
+ health_report["issues"].append({
69
+ "type": "critical",
70
+ "message": f"Low disk space on {partition['mount_point']}: {partition['used_percent']}% used",
71
+ "suggestion": "Clean up unnecessary files or resize the partition"
72
+ })
73
+ elif partition.get("used_percent", 0) > 80:
74
+ health_report["issues"].append({
75
+ "type": "warning",
76
+ "message": f"Disk space getting low on {partition['mount_point']}: {partition['used_percent']}% used",
77
+ "suggestion": "Consider cleaning up files to free up space"
78
+ })
79
+
80
+ # Failed services check
81
+ logger.info("Checking for failed services")
82
+ failed_services = await check_failed_services()
83
+ health_report["services"] = failed_services
84
+
85
+ if failed_services.get("status") == "success" and failed_services.get("data"):
86
+ health_report["issues"].append({
87
+ "type": "warning",
88
+ "message": f"{len(failed_services['data'])} failed systemd services detected",
89
+ "suggestion": "Check systemd journal logs for details about failed services"
90
+ })
91
+
92
+ # Pacman cache statistics
93
+ logger.info("Checking pacman cache")
94
+ cache_stats = await get_pacman_cache_stats()
95
+ health_report["pacman_cache"] = cache_stats
96
+
97
+ if cache_stats.get("status") == "success":
98
+ cache_size = cache_stats.get("data", {}).get("total_size_mb", 0)
99
+ if cache_size > 5000: # 5GB
100
+ health_report["suggestions"].append({
101
+ "message": f"Pacman cache is large ({cache_size:.1f}MB)",
102
+ "action": "Run 'paccache -r' to clean old packages"
103
+ })
104
+
105
+ # Updates check
106
+ logger.info("Checking for available updates")
107
+ updates = await check_updates_dry_run()
108
+ health_report["updates"] = updates
109
+
110
+ if updates.get("status") == "success":
111
+ if updates.get("updates_available"):
112
+ count = updates.get("count", 0)
113
+ health_report["suggestions"].append({
114
+ "message": f"{count} updates available",
115
+ "action": "Run 'sudo pacman -Syu' to update the system"
116
+ })
117
+
118
+ # Critical news check
119
+ logger.info("Checking for critical news")
120
+ critical_news = await check_critical_news()
121
+ health_report["news"] = critical_news
122
+
123
+ if critical_news.get("status") == "success" and critical_news.get("data"):
124
+ health_report["issues"].append({
125
+ "type": "critical",
126
+ "message": f"{len(critical_news['data'])} critical news items require attention",
127
+ "suggestion": "Review the news items before updating"
128
+ })
129
+
130
+ # Orphan packages check
131
+ logger.info("Checking for orphan packages")
132
+ orphans = await list_orphan_packages()
133
+ health_report["orphans"] = orphans
134
+
135
+ if orphans.get("status") == "success":
136
+ orphan_count = len(orphans.get("data", []))
137
+ if orphan_count > 0:
138
+ health_report["suggestions"].append({
139
+ "message": f"{orphan_count} orphan packages detected",
140
+ "action": "Run 'sudo pacman -Rns $(pacman -Qtdq)' to remove orphans"
141
+ })
142
+
143
+ # Database freshness
144
+ logger.info("Checking database freshness")
145
+ db_freshness = await check_database_freshness()
146
+ health_report["database"] = db_freshness
147
+
148
+ # Mirrorlist health
149
+ logger.info("Checking mirrorlist health")
150
+ mirror_health = await check_mirrorlist_health()
151
+ health_report["mirrors"] = mirror_health
152
+
153
+ if mirror_health.get("status") == "success":
154
+ if not mirror_health.get("data", {}).get("healthy", True):
155
+ health_report["issues"].append({
156
+ "type": "warning",
157
+ "message": "Mirrorlist configuration has issues",
158
+ "suggestion": "Run 'reflector' to update your mirrorlist"
159
+ })
160
+
161
+ # Overall health assessment
162
+ issue_count = len(health_report["issues"])
163
+ suggestion_count = len(health_report["suggestions"])
164
+
165
+ health_report["summary"] = {
166
+ "total_issues": issue_count,
167
+ "critical_issues": len([i for i in health_report["issues"] if i["type"] == "critical"]),
168
+ "warnings": len([i for i in health_report["issues"] if i["type"] == "warning"]),
169
+ "suggestions": suggestion_count
170
+ }
171
+
172
+ logger.info(f"Health check completed: {issue_count} issues, {suggestion_count} suggestions")
173
+
174
+ return health_report
175
+
176
+ except Exception as e:
177
+ logger.error(f"Health check failed: {e}")
178
+ return {
179
+ "status": "error",
180
+ "error": str(e),
181
+ "issues": [],
182
+ "suggestions": [],
183
+ "summary": {
184
+ "total_issues": 1,
185
+ "critical_issues": 1,
186
+ "warnings": 0,
187
+ "suggestions": 0
188
+ }
189
+ }
@@ -457,6 +457,25 @@ TOOL_METADATA = {
457
457
  related_tools=["analyze_pacman_conf"],
458
458
  prerequisite_tools=[]
459
459
  ),
460
+ "run_system_health_check": ToolMetadata(
461
+ name="run_system_health_check",
462
+ category="monitoring",
463
+ platform="arch",
464
+ permission="read",
465
+ workflow="diagnose",
466
+ related_tools=[
467
+ "get_system_info",
468
+ "check_disk_space",
469
+ "check_failed_services",
470
+ "get_pacman_cache_stats",
471
+ "check_updates_dry_run",
472
+ "check_critical_news",
473
+ "list_orphan_packages",
474
+ "check_database_freshness",
475
+ "check_mirrorlist_health"
476
+ ],
477
+ prerequisite_tools=[]
478
+ ),
460
479
  }
461
480
 
462
481