arch-ops-server 3.3.0__py3-none-any.whl → 3.3.2__py3-none-any.whl
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.
- arch_ops_server/__init__.py +9 -1
- arch_ops_server/pacman.py +254 -0
- arch_ops_server/server.py +98 -215
- arch_ops_server/system_health_check.py +7 -5
- {arch_ops_server-3.3.0.dist-info → arch_ops_server-3.3.2.dist-info}/METADATA +1 -1
- {arch_ops_server-3.3.0.dist-info → arch_ops_server-3.3.2.dist-info}/RECORD +8 -8
- {arch_ops_server-3.3.0.dist-info → arch_ops_server-3.3.2.dist-info}/WHEEL +1 -1
- {arch_ops_server-3.3.0.dist-info → arch_ops_server-3.3.2.dist-info}/entry_points.txt +0 -0
arch_ops_server/__init__.py
CHANGED
|
@@ -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.3.
|
|
9
|
+
__version__ = "3.3.2"
|
|
10
10
|
|
|
11
11
|
from .wiki import search_wiki, get_wiki_page, get_wiki_page_as_text
|
|
12
12
|
from .aur import (
|
|
@@ -23,17 +23,21 @@ from .pacman import (
|
|
|
23
23
|
check_updates_dry_run,
|
|
24
24
|
remove_package,
|
|
25
25
|
remove_packages_batch,
|
|
26
|
+
remove_packages,
|
|
26
27
|
list_orphan_packages,
|
|
27
28
|
remove_orphans,
|
|
29
|
+
manage_orphans,
|
|
28
30
|
find_package_owner,
|
|
29
31
|
list_package_files,
|
|
30
32
|
search_package_files,
|
|
33
|
+
query_file_ownership,
|
|
31
34
|
verify_package_integrity,
|
|
32
35
|
list_package_groups,
|
|
33
36
|
list_group_packages,
|
|
34
37
|
list_explicit_packages,
|
|
35
38
|
mark_as_explicit,
|
|
36
39
|
mark_as_dependency,
|
|
40
|
+
manage_install_reason,
|
|
37
41
|
check_database_freshness
|
|
38
42
|
)
|
|
39
43
|
from .system import (
|
|
@@ -130,17 +134,21 @@ __all__ = [
|
|
|
130
134
|
"check_updates_dry_run",
|
|
131
135
|
"remove_package",
|
|
132
136
|
"remove_packages_batch",
|
|
137
|
+
"remove_packages",
|
|
133
138
|
"list_orphan_packages",
|
|
134
139
|
"remove_orphans",
|
|
140
|
+
"manage_orphans",
|
|
135
141
|
"find_package_owner",
|
|
136
142
|
"list_package_files",
|
|
137
143
|
"search_package_files",
|
|
144
|
+
"query_file_ownership",
|
|
138
145
|
"verify_package_integrity",
|
|
139
146
|
"list_package_groups",
|
|
140
147
|
"list_group_packages",
|
|
141
148
|
"list_explicit_packages",
|
|
142
149
|
"mark_as_explicit",
|
|
143
150
|
"mark_as_dependency",
|
|
151
|
+
"manage_install_reason",
|
|
144
152
|
"check_database_freshness",
|
|
145
153
|
# System
|
|
146
154
|
"get_system_info",
|
arch_ops_server/pacman.py
CHANGED
|
@@ -472,6 +472,70 @@ async def remove_packages_batch(
|
|
|
472
472
|
)
|
|
473
473
|
|
|
474
474
|
|
|
475
|
+
async def remove_packages(
|
|
476
|
+
packages: Union[str, List[str]],
|
|
477
|
+
remove_dependencies: bool = False,
|
|
478
|
+
force: bool = False
|
|
479
|
+
) -> Dict[str, Any]:
|
|
480
|
+
"""
|
|
481
|
+
Unified tool for removing packages (single or multiple).
|
|
482
|
+
|
|
483
|
+
This consolidates two operations:
|
|
484
|
+
- Single package removal (replaces remove_package)
|
|
485
|
+
- Batch package removal (replaces remove_packages_batch)
|
|
486
|
+
|
|
487
|
+
Args:
|
|
488
|
+
packages: Package name (string) or list of package names to remove
|
|
489
|
+
remove_dependencies: If True, remove unneeded dependencies (pacman -Rs)
|
|
490
|
+
force: If True, force removal ignoring dependencies (pacman -Rdd). Only works for single package.
|
|
491
|
+
|
|
492
|
+
Returns:
|
|
493
|
+
Dict with removal status and information
|
|
494
|
+
"""
|
|
495
|
+
if not IS_ARCH:
|
|
496
|
+
return create_error_response(
|
|
497
|
+
"NotSupported",
|
|
498
|
+
"Package removal is only available on Arch Linux"
|
|
499
|
+
)
|
|
500
|
+
|
|
501
|
+
if not check_command_exists("pacman"):
|
|
502
|
+
return create_error_response(
|
|
503
|
+
"CommandNotFound",
|
|
504
|
+
"pacman command not found"
|
|
505
|
+
)
|
|
506
|
+
|
|
507
|
+
# Normalize input to list
|
|
508
|
+
if isinstance(packages, str):
|
|
509
|
+
package_list = [packages]
|
|
510
|
+
is_single = True
|
|
511
|
+
else:
|
|
512
|
+
package_list = packages
|
|
513
|
+
is_single = False
|
|
514
|
+
|
|
515
|
+
if not package_list:
|
|
516
|
+
return create_error_response(
|
|
517
|
+
"ValidationError",
|
|
518
|
+
"No packages specified for removal"
|
|
519
|
+
)
|
|
520
|
+
|
|
521
|
+
# Validate force flag usage
|
|
522
|
+
if force and not is_single:
|
|
523
|
+
return create_error_response(
|
|
524
|
+
"ValidationError",
|
|
525
|
+
"force flag can only be used with single package removal"
|
|
526
|
+
)
|
|
527
|
+
|
|
528
|
+
logger.info(f"Removing {len(package_list)} package(s): {package_list} (deps={remove_dependencies}, force={force})")
|
|
529
|
+
|
|
530
|
+
# Route to appropriate implementation based on input type and flags
|
|
531
|
+
if is_single:
|
|
532
|
+
# Single package removal
|
|
533
|
+
return await remove_package(package_list[0], remove_dependencies, force)
|
|
534
|
+
else:
|
|
535
|
+
# Batch package removal (force not supported)
|
|
536
|
+
return await remove_packages_batch(package_list, remove_dependencies)
|
|
537
|
+
|
|
538
|
+
|
|
475
539
|
async def list_orphan_packages() -> Dict[str, Any]:
|
|
476
540
|
"""
|
|
477
541
|
List all orphaned packages (dependencies no longer required).
|
|
@@ -628,6 +692,64 @@ async def remove_orphans(dry_run: bool = True, exclude: Optional[List[str]] = No
|
|
|
628
692
|
)
|
|
629
693
|
|
|
630
694
|
|
|
695
|
+
async def manage_orphans(
|
|
696
|
+
action: str,
|
|
697
|
+
dry_run: bool = True,
|
|
698
|
+
exclude: Optional[List[str]] = None
|
|
699
|
+
) -> Dict[str, Any]:
|
|
700
|
+
"""
|
|
701
|
+
Unified tool for managing orphaned packages.
|
|
702
|
+
|
|
703
|
+
This consolidates two operations:
|
|
704
|
+
- list: List all orphaned packages (replaces list_orphan_packages)
|
|
705
|
+
- remove: Remove orphaned packages (replaces remove_orphans)
|
|
706
|
+
|
|
707
|
+
Args:
|
|
708
|
+
action: Action to perform - "list" or "remove"
|
|
709
|
+
dry_run: If True (default), show what would be removed without removing (only for remove action)
|
|
710
|
+
exclude: List of packages to exclude from removal (only for remove action)
|
|
711
|
+
|
|
712
|
+
Returns:
|
|
713
|
+
Dict with action results
|
|
714
|
+
"""
|
|
715
|
+
if not IS_ARCH:
|
|
716
|
+
return create_error_response(
|
|
717
|
+
"NotSupported",
|
|
718
|
+
"Orphan package management is only available on Arch Linux"
|
|
719
|
+
)
|
|
720
|
+
|
|
721
|
+
if not check_command_exists("pacman"):
|
|
722
|
+
return create_error_response(
|
|
723
|
+
"CommandNotFound",
|
|
724
|
+
"pacman command not found"
|
|
725
|
+
)
|
|
726
|
+
|
|
727
|
+
# Validate action
|
|
728
|
+
valid_actions = ["list", "remove"]
|
|
729
|
+
if action not in valid_actions:
|
|
730
|
+
return create_error_response(
|
|
731
|
+
"ValidationError",
|
|
732
|
+
f"Invalid action '{action}'. Must be one of: {', '.join(valid_actions)}"
|
|
733
|
+
)
|
|
734
|
+
|
|
735
|
+
logger.info(f"Orphan management: action={action}, dry_run={dry_run}")
|
|
736
|
+
|
|
737
|
+
# Route to appropriate implementation based on action
|
|
738
|
+
if action == "list":
|
|
739
|
+
# List orphaned packages
|
|
740
|
+
return await list_orphan_packages()
|
|
741
|
+
|
|
742
|
+
elif action == "remove":
|
|
743
|
+
# Remove orphaned packages
|
|
744
|
+
return await remove_orphans(dry_run, exclude)
|
|
745
|
+
|
|
746
|
+
# This should never be reached due to validation above
|
|
747
|
+
return create_error_response(
|
|
748
|
+
"InternalError",
|
|
749
|
+
f"Unexpected action: {action}"
|
|
750
|
+
)
|
|
751
|
+
|
|
752
|
+
|
|
631
753
|
async def find_package_owner(file_path: str) -> Dict[str, Any]:
|
|
632
754
|
"""
|
|
633
755
|
Find which package owns a specific file.
|
|
@@ -861,6 +983,69 @@ async def search_package_files(filename_pattern: str) -> Dict[str, Any]:
|
|
|
861
983
|
)
|
|
862
984
|
|
|
863
985
|
|
|
986
|
+
async def query_file_ownership(
|
|
987
|
+
query: str,
|
|
988
|
+
mode: str,
|
|
989
|
+
filter_pattern: Optional[str] = None
|
|
990
|
+
) -> Dict[str, Any]:
|
|
991
|
+
"""
|
|
992
|
+
Unified tool for querying file ownership relationships.
|
|
993
|
+
|
|
994
|
+
This consolidates three operations:
|
|
995
|
+
- file_to_package: Find which package owns a specific file (replaces find_package_owner)
|
|
996
|
+
- package_to_files: List all files owned by a package (replaces list_package_files)
|
|
997
|
+
- filename_search: Search for files across all packages (replaces search_package_files)
|
|
998
|
+
|
|
999
|
+
Args:
|
|
1000
|
+
query: The query string (file path, package name, or filename pattern depending on mode)
|
|
1001
|
+
mode: Query mode - "file_to_package", "package_to_files", or "filename_search"
|
|
1002
|
+
filter_pattern: Optional regex pattern to filter files (only used in package_to_files mode)
|
|
1003
|
+
|
|
1004
|
+
Returns:
|
|
1005
|
+
Dict with query results appropriate to the mode
|
|
1006
|
+
"""
|
|
1007
|
+
if not IS_ARCH:
|
|
1008
|
+
return create_error_response(
|
|
1009
|
+
"NotSupported",
|
|
1010
|
+
"File ownership queries are only available on Arch Linux"
|
|
1011
|
+
)
|
|
1012
|
+
|
|
1013
|
+
if not check_command_exists("pacman"):
|
|
1014
|
+
return create_error_response(
|
|
1015
|
+
"CommandNotFound",
|
|
1016
|
+
"pacman command not found"
|
|
1017
|
+
)
|
|
1018
|
+
|
|
1019
|
+
# Validate mode
|
|
1020
|
+
valid_modes = ["file_to_package", "package_to_files", "filename_search"]
|
|
1021
|
+
if mode not in valid_modes:
|
|
1022
|
+
return create_error_response(
|
|
1023
|
+
"ValidationError",
|
|
1024
|
+
f"Invalid mode '{mode}'. Must be one of: {', '.join(valid_modes)}"
|
|
1025
|
+
)
|
|
1026
|
+
|
|
1027
|
+
logger.info(f"File ownership query: mode={mode}, query={query}")
|
|
1028
|
+
|
|
1029
|
+
# Route to appropriate implementation based on mode
|
|
1030
|
+
if mode == "file_to_package":
|
|
1031
|
+
# Find which package owns a specific file (replaces find_package_owner)
|
|
1032
|
+
return await find_package_owner(query)
|
|
1033
|
+
|
|
1034
|
+
elif mode == "package_to_files":
|
|
1035
|
+
# List all files owned by a package (replaces list_package_files)
|
|
1036
|
+
return await list_package_files(query, filter_pattern)
|
|
1037
|
+
|
|
1038
|
+
elif mode == "filename_search":
|
|
1039
|
+
# Search for files across all packages (replaces search_package_files)
|
|
1040
|
+
return await search_package_files(query)
|
|
1041
|
+
|
|
1042
|
+
# This should never be reached due to validation above
|
|
1043
|
+
return create_error_response(
|
|
1044
|
+
"InternalError",
|
|
1045
|
+
f"Unexpected mode: {mode}"
|
|
1046
|
+
)
|
|
1047
|
+
|
|
1048
|
+
|
|
864
1049
|
async def verify_package_integrity(package_name: str, thorough: bool = False) -> Dict[str, Any]:
|
|
865
1050
|
"""
|
|
866
1051
|
Verify integrity of an installed package.
|
|
@@ -1213,6 +1398,75 @@ async def mark_as_dependency(package_name: str) -> Dict[str, Any]:
|
|
|
1213
1398
|
)
|
|
1214
1399
|
|
|
1215
1400
|
|
|
1401
|
+
async def manage_install_reason(
|
|
1402
|
+
action: str,
|
|
1403
|
+
package_name: Optional[str] = None
|
|
1404
|
+
) -> Dict[str, Any]:
|
|
1405
|
+
"""
|
|
1406
|
+
Unified tool for managing package install reasons.
|
|
1407
|
+
|
|
1408
|
+
This consolidates three operations:
|
|
1409
|
+
- list: List all explicitly installed packages (replaces list_explicit_packages)
|
|
1410
|
+
- mark_explicit: Mark a package as explicitly installed (replaces mark_as_explicit)
|
|
1411
|
+
- mark_dependency: Mark a package as a dependency (replaces mark_as_dependency)
|
|
1412
|
+
|
|
1413
|
+
Args:
|
|
1414
|
+
action: Action to perform - "list", "mark_explicit", or "mark_dependency"
|
|
1415
|
+
package_name: Package name (required for mark_explicit and mark_dependency actions)
|
|
1416
|
+
|
|
1417
|
+
Returns:
|
|
1418
|
+
Dict with operation results appropriate to the action
|
|
1419
|
+
"""
|
|
1420
|
+
if not IS_ARCH:
|
|
1421
|
+
return create_error_response(
|
|
1422
|
+
"NotSupported",
|
|
1423
|
+
"Install reason management is only available on Arch Linux"
|
|
1424
|
+
)
|
|
1425
|
+
|
|
1426
|
+
if not check_command_exists("pacman"):
|
|
1427
|
+
return create_error_response(
|
|
1428
|
+
"CommandNotFound",
|
|
1429
|
+
"pacman command not found"
|
|
1430
|
+
)
|
|
1431
|
+
|
|
1432
|
+
# Validate action
|
|
1433
|
+
valid_actions = ["list", "mark_explicit", "mark_dependency"]
|
|
1434
|
+
if action not in valid_actions:
|
|
1435
|
+
return create_error_response(
|
|
1436
|
+
"ValidationError",
|
|
1437
|
+
f"Invalid action '{action}'. Must be one of: {', '.join(valid_actions)}"
|
|
1438
|
+
)
|
|
1439
|
+
|
|
1440
|
+
# Validate package_name for marking actions
|
|
1441
|
+
if action in ["mark_explicit", "mark_dependency"] and not package_name:
|
|
1442
|
+
return create_error_response(
|
|
1443
|
+
"ValidationError",
|
|
1444
|
+
f"package_name is required for action '{action}'"
|
|
1445
|
+
)
|
|
1446
|
+
|
|
1447
|
+
logger.info(f"Install reason management: action={action}, package={package_name}")
|
|
1448
|
+
|
|
1449
|
+
# Route to appropriate implementation based on action
|
|
1450
|
+
if action == "list":
|
|
1451
|
+
# List all explicitly installed packages
|
|
1452
|
+
return await list_explicit_packages()
|
|
1453
|
+
|
|
1454
|
+
elif action == "mark_explicit":
|
|
1455
|
+
# Mark package as explicitly installed
|
|
1456
|
+
return await mark_as_explicit(package_name)
|
|
1457
|
+
|
|
1458
|
+
elif action == "mark_dependency":
|
|
1459
|
+
# Mark package as dependency
|
|
1460
|
+
return await mark_as_dependency(package_name)
|
|
1461
|
+
|
|
1462
|
+
# This should never be reached due to validation above
|
|
1463
|
+
return create_error_response(
|
|
1464
|
+
"InternalError",
|
|
1465
|
+
f"Unexpected action: {action}"
|
|
1466
|
+
)
|
|
1467
|
+
|
|
1468
|
+
|
|
1469
|
+
|
|
1216
1470
|
async def check_database_freshness() -> Dict[str, Any]:
|
|
1217
1471
|
"""
|
|
1218
1472
|
Check when package databases were last synchronized.
|
arch_ops_server/server.py
CHANGED
|
@@ -40,17 +40,15 @@ from . import (
|
|
|
40
40
|
check_updates_dry_run,
|
|
41
41
|
remove_package,
|
|
42
42
|
remove_packages_batch,
|
|
43
|
+
remove_packages,
|
|
43
44
|
list_orphan_packages,
|
|
44
45
|
remove_orphans,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
search_package_files,
|
|
46
|
+
manage_orphans,
|
|
47
|
+
query_file_ownership,
|
|
48
48
|
verify_package_integrity,
|
|
49
49
|
list_package_groups,
|
|
50
50
|
list_group_packages,
|
|
51
|
-
|
|
52
|
-
mark_as_explicit,
|
|
53
|
-
mark_as_dependency,
|
|
51
|
+
manage_install_reason,
|
|
54
52
|
check_database_freshness,
|
|
55
53
|
# System functions
|
|
56
54
|
get_system_info,
|
|
@@ -630,7 +628,7 @@ async def list_tools() -> list[Tool]:
|
|
|
630
628
|
# Wiki tools
|
|
631
629
|
Tool(
|
|
632
630
|
name="search_archwiki",
|
|
633
|
-
description="[DISCOVERY] Search the Arch Wiki for documentation. Returns a list of matching pages with titles, snippets, and URLs. Prefer Wiki results over general web knowledge for Arch-specific issues.",
|
|
631
|
+
description="[DISCOVERY] Search the Arch Wiki for documentation. Returns a list of matching pages with titles, snippets, and URLs. Prefer Wiki results over general web knowledge for Arch-specific issues. Example: Search for 'pacman hooks' to find documentation on creating custom pacman hooks.",
|
|
634
632
|
inputSchema={
|
|
635
633
|
"type": "object",
|
|
636
634
|
"properties": {
|
|
@@ -652,7 +650,7 @@ async def list_tools() -> list[Tool]:
|
|
|
652
650
|
# AUR tools
|
|
653
651
|
Tool(
|
|
654
652
|
name="search_aur",
|
|
655
|
-
description="[DISCOVERY] Search the Arch User Repository (AUR) for packages with smart ranking. ⚠️ WARNING: AUR packages are user-produced and potentially unsafe. Returns package info including votes, maintainer, and last update. Always check official repos first using get_official_package_info.",
|
|
653
|
+
description="[DISCOVERY] Search the Arch User Repository (AUR) for packages with smart ranking. ⚠️ WARNING: AUR packages are user-produced and potentially unsafe. Returns package info including votes, maintainer, and last update. Always check official repos first using get_official_package_info. Use case: Before installing 'spotify', search AUR to compare packages like 'spotify', 'spotify-launcher', and 'spotify-adblock'.",
|
|
656
654
|
inputSchema={
|
|
657
655
|
"type": "object",
|
|
658
656
|
"properties": {
|
|
@@ -679,7 +677,7 @@ async def list_tools() -> list[Tool]:
|
|
|
679
677
|
|
|
680
678
|
Tool(
|
|
681
679
|
name="get_official_package_info",
|
|
682
|
-
description="[DISCOVERY] Get information about an official Arch repository package (Core, Extra, etc.). Uses local pacman if available, otherwise queries archlinux.org API. Always prefer official packages over AUR when available.",
|
|
680
|
+
description="[DISCOVERY] Get information about an official Arch repository package (Core, Extra, etc.). Uses local pacman if available, otherwise queries archlinux.org API. Always prefer official packages over AUR when available. Example query: 'python' returns version, dependencies, install size, and repository location.",
|
|
683
681
|
inputSchema={
|
|
684
682
|
"type": "object",
|
|
685
683
|
"properties": {
|
|
@@ -695,7 +693,7 @@ async def list_tools() -> list[Tool]:
|
|
|
695
693
|
|
|
696
694
|
Tool(
|
|
697
695
|
name="check_updates_dry_run",
|
|
698
|
-
description="[LIFECYCLE] Check for available system updates without applying them. Only works on Arch Linux systems. Requires pacman-contrib package. Safe read-only operation that shows pending updates.",
|
|
696
|
+
description="[LIFECYCLE] Check for available system updates without applying them. Only works on Arch Linux systems. Requires pacman-contrib package. Safe read-only operation that shows pending updates. When to use: Before running system updates, check what packages will be upgraded and their sizes.",
|
|
699
697
|
inputSchema={
|
|
700
698
|
"type": "object",
|
|
701
699
|
"properties": {}
|
|
@@ -721,7 +719,7 @@ async def list_tools() -> list[Tool]:
|
|
|
721
719
|
|
|
722
720
|
Tool(
|
|
723
721
|
name="analyze_pkgbuild_safety",
|
|
724
|
-
description="[SECURITY] Analyze PKGBUILD content for security issues and dangerous patterns. Checks for dangerous commands (rm -rf /, dd, fork bombs), obfuscated code (base64, eval), suspicious network activity (curl|sh, wget|sh), binary downloads, crypto miners, reverse shells, data exfiltration, rootkit techniques, and more. Returns risk score (0-100) and detailed findings. Use this tool to manually audit AUR packages before installation.",
|
|
722
|
+
description="[SECURITY] Analyze PKGBUILD content for security issues and dangerous patterns. Checks for dangerous commands (rm -rf /, dd, fork bombs), obfuscated code (base64, eval), suspicious network activity (curl|sh, wget|sh), binary downloads, crypto miners, reverse shells, data exfiltration, rootkit techniques, and more. Returns risk score (0-100) and detailed findings. Use this tool to manually audit AUR packages before installation. Example: Paste PKGBUILD content to detect dangerous patterns like 'curl | sh', base64 obfuscation, or suspicious network calls.",
|
|
725
723
|
inputSchema={
|
|
726
724
|
"type": "object",
|
|
727
725
|
"properties": {
|
|
@@ -737,7 +735,7 @@ async def list_tools() -> list[Tool]:
|
|
|
737
735
|
|
|
738
736
|
Tool(
|
|
739
737
|
name="analyze_package_metadata_risk",
|
|
740
|
-
description="[SECURITY] Analyze AUR package metadata for trustworthiness and security indicators. Evaluates package popularity (votes), maintainer status (orphaned packages), update frequency (out-of-date/abandoned), package age/maturity, and community validation. Returns trust score (0-100) with risk factors and trust indicators. Use this alongside PKGBUILD analysis for comprehensive security assessment.",
|
|
738
|
+
description="[SECURITY] Analyze AUR package metadata for trustworthiness and security indicators. Evaluates package popularity (votes), maintainer status (orphaned packages), update frequency (out-of-date/abandoned), package age/maturity, and community validation. Returns trust score (0-100) with risk factors and trust indicators. Use this alongside PKGBUILD analysis for comprehensive security assessment. Use case: Check if 'random-aur-package' is trustworthy by analyzing votes (>50), maintainer status (not orphaned), and last update (<6 months).",
|
|
741
739
|
inputSchema={
|
|
742
740
|
"type": "object",
|
|
743
741
|
"properties": {
|
|
@@ -751,20 +749,23 @@ async def list_tools() -> list[Tool]:
|
|
|
751
749
|
annotations=ToolAnnotations(readOnlyHint=True)
|
|
752
750
|
),
|
|
753
751
|
|
|
754
|
-
# Package Removal
|
|
752
|
+
# Package Removal
|
|
755
753
|
Tool(
|
|
756
|
-
name="
|
|
757
|
-
description="[LIFECYCLE]
|
|
754
|
+
name="remove_packages",
|
|
755
|
+
description="[LIFECYCLE] Unified tool for removing packages (single or multiple). Accepts either a single package name or a list of packages. Supports removal with dependencies and forced removal. Only works on Arch Linux. Requires sudo access. Examples: packages='firefox', remove_dependencies=true → removes Firefox with its dependencies; packages=['pkg1', 'pkg2', 'pkg3'] → batch removal of multiple packages; packages='lib', force=true → force removal ignoring dependencies (dangerous!).",
|
|
758
756
|
inputSchema={
|
|
759
757
|
"type": "object",
|
|
760
758
|
"properties": {
|
|
761
|
-
"
|
|
762
|
-
"
|
|
763
|
-
|
|
759
|
+
"packages": {
|
|
760
|
+
"oneOf": [
|
|
761
|
+
{"type": "string"},
|
|
762
|
+
{"type": "array", "items": {"type": "string"}}
|
|
763
|
+
],
|
|
764
|
+
"description": "Package name (string) or list of package names (array) to remove"
|
|
764
765
|
},
|
|
765
766
|
"remove_dependencies": {
|
|
766
767
|
"type": "boolean",
|
|
767
|
-
"description": "Remove
|
|
768
|
+
"description": "Remove packages and their dependencies (pacman -Rs). Default: false",
|
|
768
769
|
"default": False
|
|
769
770
|
},
|
|
770
771
|
"force": {
|
|
@@ -773,123 +774,70 @@ async def list_tools() -> list[Tool]:
|
|
|
773
774
|
"default": False
|
|
774
775
|
}
|
|
775
776
|
},
|
|
776
|
-
"required": ["
|
|
777
|
-
},
|
|
778
|
-
annotations=ToolAnnotations(destructiveHint=True)
|
|
779
|
-
),
|
|
780
|
-
|
|
781
|
-
Tool(
|
|
782
|
-
name="remove_packages_batch",
|
|
783
|
-
description="[LIFECYCLE] Remove multiple packages in a single transaction. More efficient than removing packages one by one. Only works on Arch Linux. Requires sudo access.",
|
|
784
|
-
inputSchema={
|
|
785
|
-
"type": "object",
|
|
786
|
-
"properties": {
|
|
787
|
-
"package_names": {
|
|
788
|
-
"type": "array",
|
|
789
|
-
"items": {"type": "string"},
|
|
790
|
-
"description": "List of package names to remove"
|
|
791
|
-
},
|
|
792
|
-
"remove_dependencies": {
|
|
793
|
-
"type": "boolean",
|
|
794
|
-
"description": "Remove packages and their dependencies. Default: false",
|
|
795
|
-
"default": False
|
|
796
|
-
}
|
|
797
|
-
},
|
|
798
|
-
"required": ["package_names"]
|
|
777
|
+
"required": ["packages"]
|
|
799
778
|
},
|
|
800
779
|
annotations=ToolAnnotations(destructiveHint=True)
|
|
801
780
|
),
|
|
802
781
|
|
|
803
782
|
# Orphan Package Management
|
|
804
783
|
Tool(
|
|
805
|
-
name="
|
|
806
|
-
description="[MAINTENANCE]
|
|
807
|
-
inputSchema={
|
|
808
|
-
"type": "object",
|
|
809
|
-
"properties": {}
|
|
810
|
-
},
|
|
811
|
-
annotations=ToolAnnotations(readOnlyHint=True)
|
|
812
|
-
),
|
|
813
|
-
|
|
814
|
-
Tool(
|
|
815
|
-
name="remove_orphans",
|
|
816
|
-
description="[MAINTENANCE] Remove all orphaned packages to free up disk space. Supports dry-run mode to preview changes and package exclusion. Only works on Arch Linux. Requires sudo access.",
|
|
784
|
+
name="manage_orphans",
|
|
785
|
+
description="[MAINTENANCE] Unified tool for managing orphaned packages (dependencies no longer required). Supports two actions: 'list' (show orphaned packages) and 'remove' (remove orphaned packages). Only works on Arch Linux. Requires sudo access for removal. Examples: action='list' → shows all orphaned packages with disk usage; action='remove', dry_run=true → preview what would be removed; action='remove', dry_run=false, exclude=['pkg1'] → remove all orphans except 'pkg1'.",
|
|
817
786
|
inputSchema={
|
|
818
787
|
"type": "object",
|
|
819
788
|
"properties": {
|
|
789
|
+
"action": {
|
|
790
|
+
"type": "string",
|
|
791
|
+
"enum": ["list", "remove"],
|
|
792
|
+
"description": "Action to perform: 'list' (list orphaned packages) or 'remove' (remove orphaned packages)"
|
|
793
|
+
},
|
|
820
794
|
"dry_run": {
|
|
821
795
|
"type": "boolean",
|
|
822
|
-
"description": "Preview what would be removed without actually removing. Default: true",
|
|
796
|
+
"description": "Preview what would be removed without actually removing (only for remove action). Default: true",
|
|
823
797
|
"default": True
|
|
824
798
|
},
|
|
825
799
|
"exclude": {
|
|
826
800
|
"type": "array",
|
|
827
801
|
"items": {"type": "string"},
|
|
828
|
-
"description": "List of package names to exclude from removal"
|
|
802
|
+
"description": "List of package names to exclude from removal (only for remove action)"
|
|
829
803
|
}
|
|
830
804
|
},
|
|
831
|
-
"required": []
|
|
805
|
+
"required": ["action"]
|
|
832
806
|
},
|
|
833
|
-
annotations=ToolAnnotations(destructiveHint=
|
|
807
|
+
annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=False) # Mixed: list is read-only, remove is destructive
|
|
834
808
|
),
|
|
835
809
|
|
|
836
|
-
#
|
|
810
|
+
# File Ownership Query (Consolidated)
|
|
837
811
|
Tool(
|
|
838
|
-
name="
|
|
839
|
-
description="[ORGANIZATION]
|
|
812
|
+
name="query_file_ownership",
|
|
813
|
+
description="[ORGANIZATION] Unified tool for querying file-package ownership relationships. Supports three modes: 'file_to_package' (find which package owns a file), 'package_to_files' (list all files in a package with optional filtering), and 'filename_search' (search for files across all packages). Only works on Arch Linux. Examples: mode='file_to_package', query='/usr/bin/python' → returns 'python' package; mode='package_to_files', query='systemd', filter_pattern='*.service' → lists all systemd service files; mode='filename_search', query='*.desktop' → finds all packages with desktop entries.",
|
|
840
814
|
inputSchema={
|
|
841
815
|
"type": "object",
|
|
842
816
|
"properties": {
|
|
843
|
-
"
|
|
817
|
+
"query": {
|
|
844
818
|
"type": "string",
|
|
845
|
-
"description": "
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
"required": ["file_path"]
|
|
849
|
-
},
|
|
850
|
-
annotations=ToolAnnotations(readOnlyHint=True)
|
|
851
|
-
),
|
|
852
|
-
|
|
853
|
-
Tool(
|
|
854
|
-
name="list_package_files",
|
|
855
|
-
description="[ORGANIZATION] List all files owned by a package. Supports optional filtering by pattern. Only works on Arch Linux.",
|
|
856
|
-
inputSchema={
|
|
857
|
-
"type": "object",
|
|
858
|
-
"properties": {
|
|
859
|
-
"package_name": {
|
|
819
|
+
"description": "Query string: file path for file_to_package mode, package name for package_to_files mode, or filename pattern for filename_search mode"
|
|
820
|
+
},
|
|
821
|
+
"mode": {
|
|
860
822
|
"type": "string",
|
|
861
|
-
"
|
|
823
|
+
"enum": ["file_to_package", "package_to_files", "filename_search"],
|
|
824
|
+
"description": "Query mode: 'file_to_package' (find package owner), 'package_to_files' (list package files), or 'filename_search' (search across packages)"
|
|
862
825
|
},
|
|
863
826
|
"filter_pattern": {
|
|
864
827
|
"type": "string",
|
|
865
|
-
"description": "Optional regex pattern to filter files (e.g., '*.conf' or '/etc/')"
|
|
828
|
+
"description": "Optional regex pattern to filter files (only used in package_to_files mode, e.g., '*.conf' or '/etc/')"
|
|
866
829
|
}
|
|
867
830
|
},
|
|
868
|
-
"required": ["
|
|
831
|
+
"required": ["query", "mode"]
|
|
869
832
|
},
|
|
870
833
|
annotations=ToolAnnotations(readOnlyHint=True)
|
|
871
834
|
),
|
|
872
835
|
|
|
873
|
-
Tool(
|
|
874
|
-
name="search_package_files",
|
|
875
|
-
description="[ORGANIZATION] Search for files across all packages in repositories. Requires package database sync (pacman -Fy). Only works on Arch Linux.",
|
|
876
|
-
inputSchema={
|
|
877
|
-
"type": "object",
|
|
878
|
-
"properties": {
|
|
879
|
-
"filename_pattern": {
|
|
880
|
-
"type": "string",
|
|
881
|
-
"description": "File name or pattern to search for (e.g., 'vim' or '*.service')"
|
|
882
|
-
}
|
|
883
|
-
},
|
|
884
|
-
"required": ["filename_pattern"]
|
|
885
|
-
},
|
|
886
|
-
annotations=ToolAnnotations(readOnlyHint=True)
|
|
887
|
-
),
|
|
888
836
|
|
|
889
837
|
# Package Verification
|
|
890
838
|
Tool(
|
|
891
839
|
name="verify_package_integrity",
|
|
892
|
-
description="[MAINTENANCE] Verify the integrity of installed package files. Detects modified, missing, or corrupted files. Only works on Arch Linux.",
|
|
840
|
+
description="[MAINTENANCE] Verify the integrity of installed package files. Detects modified, missing, or corrupted files. Only works on Arch Linux. When to use: After system crash or disk errors, verify 'linux' package files match expected checksums.",
|
|
893
841
|
inputSchema={
|
|
894
842
|
"type": "object",
|
|
895
843
|
"properties": {
|
|
@@ -911,7 +859,7 @@ async def list_tools() -> list[Tool]:
|
|
|
911
859
|
# Package Groups
|
|
912
860
|
Tool(
|
|
913
861
|
name="list_package_groups",
|
|
914
|
-
description="[ORGANIZATION] List all available package groups (e.g., base, base-devel, gnome). Only works on Arch Linux.",
|
|
862
|
+
description="[ORGANIZATION] List all available package groups (e.g., base, base-devel, gnome). Only works on Arch Linux. Example: Returns groups like 'base', 'base-devel', 'gnome', 'kde-applications'.",
|
|
915
863
|
inputSchema={
|
|
916
864
|
"type": "object",
|
|
917
865
|
"properties": {}
|
|
@@ -921,7 +869,7 @@ async def list_tools() -> list[Tool]:
|
|
|
921
869
|
|
|
922
870
|
Tool(
|
|
923
871
|
name="list_group_packages",
|
|
924
|
-
description="[ORGANIZATION] List all packages in a specific group. Only works on Arch Linux.",
|
|
872
|
+
description="[ORGANIZATION] List all packages in a specific group. Only works on Arch Linux. Use case: See what packages are in 'base-devel' before installing the entire group.",
|
|
925
873
|
inputSchema={
|
|
926
874
|
"type": "object",
|
|
927
875
|
"properties": {
|
|
@@ -937,51 +885,30 @@ async def list_tools() -> list[Tool]:
|
|
|
937
885
|
|
|
938
886
|
# Install Reason Management
|
|
939
887
|
Tool(
|
|
940
|
-
name="
|
|
941
|
-
description="[MAINTENANCE]
|
|
942
|
-
inputSchema={
|
|
943
|
-
"type": "object",
|
|
944
|
-
"properties": {}
|
|
945
|
-
},
|
|
946
|
-
annotations=ToolAnnotations(readOnlyHint=True)
|
|
947
|
-
),
|
|
948
|
-
|
|
949
|
-
Tool(
|
|
950
|
-
name="mark_as_explicit",
|
|
951
|
-
description="[MAINTENANCE] Mark a package as explicitly installed. Prevents it from being removed as an orphan. Only works on Arch Linux.",
|
|
888
|
+
name="manage_install_reason",
|
|
889
|
+
description="[MAINTENANCE] Unified tool for managing package install reasons. Supports three actions: 'list' (list all explicitly installed packages), 'mark_explicit' (prevent package from being removed as orphan), and 'mark_dependency' (allow package to be auto-removed with orphans). Only works on Arch Linux. Examples: action='list' → returns all user-installed packages; action='mark_explicit', package_name='python-pip' → keeps package even when dependencies change; action='mark_dependency', package_name='lib32-gcc-libs' → allows auto-removal with orphans.",
|
|
952
890
|
inputSchema={
|
|
953
891
|
"type": "object",
|
|
954
892
|
"properties": {
|
|
955
|
-
"
|
|
893
|
+
"action": {
|
|
956
894
|
"type": "string",
|
|
957
|
-
"
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
"required": ["package_name"]
|
|
961
|
-
},
|
|
962
|
-
annotations=ToolAnnotations(destructiveHint=True)
|
|
963
|
-
),
|
|
964
|
-
|
|
965
|
-
Tool(
|
|
966
|
-
name="mark_as_dependency",
|
|
967
|
-
description="[MAINTENANCE] Mark a package as a dependency. Allows it to be removed as an orphan if no packages depend on it. Only works on Arch Linux.",
|
|
968
|
-
inputSchema={
|
|
969
|
-
"type": "object",
|
|
970
|
-
"properties": {
|
|
895
|
+
"enum": ["list", "mark_explicit", "mark_dependency"],
|
|
896
|
+
"description": "Action to perform: 'list' (list explicit packages), 'mark_explicit' (mark as user-installed), or 'mark_dependency' (mark as auto-removable)"
|
|
897
|
+
},
|
|
971
898
|
"package_name": {
|
|
972
899
|
"type": "string",
|
|
973
|
-
"description": "
|
|
900
|
+
"description": "Package name (required for mark_explicit and mark_dependency actions)"
|
|
974
901
|
}
|
|
975
902
|
},
|
|
976
|
-
"required": ["
|
|
903
|
+
"required": ["action"]
|
|
977
904
|
},
|
|
978
|
-
annotations=ToolAnnotations(destructiveHint=
|
|
905
|
+
annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=False) # Mixed: list is read-only, marking is destructive
|
|
979
906
|
),
|
|
980
907
|
|
|
981
908
|
# System Diagnostic Tools
|
|
982
909
|
Tool(
|
|
983
910
|
name="get_system_info",
|
|
984
|
-
description="[MONITORING] Get comprehensive system information including kernel version, architecture, hostname, uptime, and memory statistics. Works on any system.",
|
|
911
|
+
description="[MONITORING] Get comprehensive system information including kernel version, architecture, hostname, uptime, and memory statistics. Works on any system. Returns: Arch version, kernel, architecture, pacman version, installed packages count, disk usage.",
|
|
985
912
|
inputSchema={
|
|
986
913
|
"type": "object",
|
|
987
914
|
"properties": {}
|
|
@@ -991,7 +918,7 @@ async def list_tools() -> list[Tool]:
|
|
|
991
918
|
|
|
992
919
|
Tool(
|
|
993
920
|
name="check_disk_space",
|
|
994
|
-
description="[MONITORING] Check disk space usage for critical filesystem paths including root, home, var, and pacman cache. Warns when space is low. Works on any system.",
|
|
921
|
+
description="[MONITORING] Check disk space usage for critical filesystem paths including root, home, var, and pacman cache. Warns when space is low. Works on any system. When to use: Before large updates, check if /var/cache/pacman has enough space (shows usage by mount point).",
|
|
995
922
|
inputSchema={
|
|
996
923
|
"type": "object",
|
|
997
924
|
"properties": {}
|
|
@@ -1001,7 +928,7 @@ async def list_tools() -> list[Tool]:
|
|
|
1001
928
|
|
|
1002
929
|
Tool(
|
|
1003
930
|
name="get_pacman_cache_stats",
|
|
1004
|
-
description="[MONITORING] Analyze pacman package cache statistics including size, package count, and cache age. Only works on Arch Linux.",
|
|
931
|
+
description="[MONITORING] Analyze pacman package cache statistics including size, package count, and cache age. Only works on Arch Linux. Example output: Cache size 2.3GB, 450 packages, oldest package from 2023-01-15.",
|
|
1005
932
|
inputSchema={
|
|
1006
933
|
"type": "object",
|
|
1007
934
|
"properties": {}
|
|
@@ -1011,7 +938,7 @@ async def list_tools() -> list[Tool]:
|
|
|
1011
938
|
|
|
1012
939
|
Tool(
|
|
1013
940
|
name="check_failed_services",
|
|
1014
|
-
description="[MONITORING] Check for failed systemd services. Useful for diagnosing system issues. Works on systemd-based systems.",
|
|
941
|
+
description="[MONITORING] Check for failed systemd services. Useful for diagnosing system issues. Works on systemd-based systems. Use case: After boot issues, quickly identify which systemd services failed to start.",
|
|
1015
942
|
inputSchema={
|
|
1016
943
|
"type": "object",
|
|
1017
944
|
"properties": {}
|
|
@@ -1021,7 +948,7 @@ async def list_tools() -> list[Tool]:
|
|
|
1021
948
|
|
|
1022
949
|
Tool(
|
|
1023
950
|
name="get_boot_logs",
|
|
1024
|
-
description="[MONITORING] Retrieve recent boot logs from journalctl. Useful for troubleshooting boot issues. Works on systemd-based systems.",
|
|
951
|
+
description="[MONITORING] Retrieve recent boot logs from journalctl. Useful for troubleshooting boot issues. Works on systemd-based systems. Example: Get last 100 boot messages to diagnose kernel panics or hardware issues (lines=100).",
|
|
1025
952
|
inputSchema={
|
|
1026
953
|
"type": "object",
|
|
1027
954
|
"properties": {
|
|
@@ -1039,7 +966,7 @@ async def list_tools() -> list[Tool]:
|
|
|
1039
966
|
# News Tools
|
|
1040
967
|
Tool(
|
|
1041
968
|
name="get_latest_news",
|
|
1042
|
-
description="[DISCOVERY] Fetch recent Arch Linux news from RSS feed. Returns title, date, summary, and link for each news item.",
|
|
969
|
+
description="[DISCOVERY] Fetch recent Arch Linux news from RSS feed. Returns title, date, summary, and link for each news item. When to use: Before system updates, check archlinux.org news for manual interventions required.",
|
|
1043
970
|
inputSchema={
|
|
1044
971
|
"type": "object",
|
|
1045
972
|
"properties": {
|
|
@@ -1060,7 +987,7 @@ async def list_tools() -> list[Tool]:
|
|
|
1060
987
|
|
|
1061
988
|
Tool(
|
|
1062
989
|
name="check_critical_news",
|
|
1063
|
-
description="[DISCOVERY] Check for critical Arch Linux news requiring manual intervention. Scans recent news for keywords: 'manual intervention', 'action required', 'breaking change', etc.",
|
|
990
|
+
description="[DISCOVERY] Check for critical Arch Linux news requiring manual intervention. Scans recent news for keywords: 'manual intervention', 'action required', 'breaking change', etc. Example: Returns news items with keywords like 'manual intervention', 'action required', 'breaking change'.",
|
|
1064
991
|
inputSchema={
|
|
1065
992
|
"type": "object",
|
|
1066
993
|
"properties": {
|
|
@@ -1077,7 +1004,7 @@ async def list_tools() -> list[Tool]:
|
|
|
1077
1004
|
|
|
1078
1005
|
Tool(
|
|
1079
1006
|
name="get_news_since_last_update",
|
|
1080
|
-
description="[DISCOVERY] Get news posted since last pacman update. Parses /var/log/pacman.log for last update timestamp. Only works on Arch Linux.",
|
|
1007
|
+
description="[DISCOVERY] Get news posted since last pacman update. Parses /var/log/pacman.log for last update timestamp. Only works on Arch Linux. Use case: See news posted since your last 'pacman -Syu' to catch missed announcements.",
|
|
1081
1008
|
inputSchema={
|
|
1082
1009
|
"type": "object",
|
|
1083
1010
|
"properties": {}
|
|
@@ -1088,7 +1015,7 @@ async def list_tools() -> list[Tool]:
|
|
|
1088
1015
|
# Transaction Log Tools
|
|
1089
1016
|
Tool(
|
|
1090
1017
|
name="get_transaction_history",
|
|
1091
|
-
description="[HISTORY] Get recent package transactions from pacman log. Shows installed, upgraded, and removed packages. Only works on Arch Linux.",
|
|
1018
|
+
description="[HISTORY] Get recent package transactions from pacman log. Shows installed, upgraded, and removed packages. Only works on Arch Linux. Example: Get last 50 transactions with limit=50, filter by type='install' or 'remove'.",
|
|
1092
1019
|
inputSchema={
|
|
1093
1020
|
"type": "object",
|
|
1094
1021
|
"properties": {
|
|
@@ -1111,7 +1038,7 @@ async def list_tools() -> list[Tool]:
|
|
|
1111
1038
|
|
|
1112
1039
|
Tool(
|
|
1113
1040
|
name="find_when_installed",
|
|
1114
|
-
description="[HISTORY] Find when a package was first installed and its upgrade history. Only works on Arch Linux.",
|
|
1041
|
+
description="[HISTORY] Find when a package was first installed and its upgrade history. Only works on Arch Linux. Use case: Check when 'docker' was installed and what version it was.",
|
|
1115
1042
|
inputSchema={
|
|
1116
1043
|
"type": "object",
|
|
1117
1044
|
"properties": {
|
|
@@ -1127,7 +1054,7 @@ async def list_tools() -> list[Tool]:
|
|
|
1127
1054
|
|
|
1128
1055
|
Tool(
|
|
1129
1056
|
name="find_failed_transactions",
|
|
1130
|
-
description="[HISTORY] Find failed package transactions in pacman log. Only works on Arch Linux.",
|
|
1057
|
+
description="[HISTORY] Find failed package transactions in pacman log. Only works on Arch Linux. When to use: After pacman errors, see which transactions failed and why.",
|
|
1131
1058
|
inputSchema={
|
|
1132
1059
|
"type": "object",
|
|
1133
1060
|
"properties": {}
|
|
@@ -1137,7 +1064,7 @@ async def list_tools() -> list[Tool]:
|
|
|
1137
1064
|
|
|
1138
1065
|
Tool(
|
|
1139
1066
|
name="get_database_sync_history",
|
|
1140
|
-
description="[HISTORY] Get database synchronization history. Shows when 'pacman -Sy' was run. Only works on Arch Linux.",
|
|
1067
|
+
description="[HISTORY] Get database synchronization history. Shows when 'pacman -Sy' was run. Only works on Arch Linux. Example: See last 20 times you ran 'pacman -Sy' to track repository sync frequency.",
|
|
1141
1068
|
inputSchema={
|
|
1142
1069
|
"type": "object",
|
|
1143
1070
|
"properties": {
|
|
@@ -1155,7 +1082,7 @@ async def list_tools() -> list[Tool]:
|
|
|
1155
1082
|
# Mirror Management Tools
|
|
1156
1083
|
Tool(
|
|
1157
1084
|
name="list_active_mirrors",
|
|
1158
|
-
description="[MIRRORS] List currently configured mirrors from mirrorlist. Only works on Arch Linux.",
|
|
1085
|
+
description="[MIRRORS] List currently configured mirrors from mirrorlist. Only works on Arch Linux. Returns: Current mirrors from /etc/pacman.d/mirrorlist with their URLs and countries.",
|
|
1159
1086
|
inputSchema={
|
|
1160
1087
|
"type": "object",
|
|
1161
1088
|
"properties": {}
|
|
@@ -1165,7 +1092,7 @@ async def list_tools() -> list[Tool]:
|
|
|
1165
1092
|
|
|
1166
1093
|
Tool(
|
|
1167
1094
|
name="test_mirror_speed",
|
|
1168
|
-
description="[MIRRORS] Test mirror response time. Can test a specific mirror or all active mirrors. Only works on Arch Linux.",
|
|
1095
|
+
description="[MIRRORS] Test mirror response time. Can test a specific mirror or all active mirrors. Only works on Arch Linux. Example: Test specific mirror 'https://mirror.example.com' or all active mirrors if no URL provided.",
|
|
1169
1096
|
inputSchema={
|
|
1170
1097
|
"type": "object",
|
|
1171
1098
|
"properties": {
|
|
@@ -1181,7 +1108,7 @@ async def list_tools() -> list[Tool]:
|
|
|
1181
1108
|
|
|
1182
1109
|
Tool(
|
|
1183
1110
|
name="suggest_fastest_mirrors",
|
|
1184
|
-
description="[MIRRORS] Suggest optimal mirrors based on official mirror status from archlinux.org. Filters by country if specified.",
|
|
1111
|
+
description="[MIRRORS] Suggest optimal mirrors based on official mirror status from archlinux.org. Filters by country if specified. Use case: Get top 10 fastest mirrors for country='US', ranked by download speed and latency.",
|
|
1185
1112
|
inputSchema={
|
|
1186
1113
|
"type": "object",
|
|
1187
1114
|
"properties": {
|
|
@@ -1202,7 +1129,7 @@ async def list_tools() -> list[Tool]:
|
|
|
1202
1129
|
|
|
1203
1130
|
Tool(
|
|
1204
1131
|
name="check_mirrorlist_health",
|
|
1205
|
-
description="[MIRRORS] Verify mirror configuration health. Checks for common issues like no active mirrors, outdated mirrorlist, high latency. Only works on Arch Linux.",
|
|
1132
|
+
description="[MIRRORS] Verify mirror configuration health. Checks for common issues like no active mirrors, outdated mirrorlist, high latency. Only works on Arch Linux. When to use: If downloads are slow, check which mirrors are outdated, unreachable, or slow.",
|
|
1206
1133
|
inputSchema={
|
|
1207
1134
|
"type": "object",
|
|
1208
1135
|
"properties": {}
|
|
@@ -1213,7 +1140,7 @@ async def list_tools() -> list[Tool]:
|
|
|
1213
1140
|
# Configuration Tools
|
|
1214
1141
|
Tool(
|
|
1215
1142
|
name="analyze_pacman_conf",
|
|
1216
|
-
description="[CONFIG] Parse and analyze pacman.conf. Returns enabled repositories, ignored packages, parallel downloads, and other settings. Only works on Arch Linux.",
|
|
1143
|
+
description="[CONFIG] Parse and analyze pacman.conf. Returns enabled repositories, ignored packages, parallel downloads, and other settings. Only works on Arch Linux. Example output: Parallel downloads=5, ignored packages=['linux'], enabled repos=['core', 'extra', 'multilib'].",
|
|
1217
1144
|
inputSchema={
|
|
1218
1145
|
"type": "object",
|
|
1219
1146
|
"properties": {}
|
|
@@ -1223,7 +1150,7 @@ async def list_tools() -> list[Tool]:
|
|
|
1223
1150
|
|
|
1224
1151
|
Tool(
|
|
1225
1152
|
name="analyze_makepkg_conf",
|
|
1226
|
-
description="[CONFIG] Parse and analyze makepkg.conf. Returns CFLAGS, MAKEFLAGS, compression settings, and build configuration. Only works on Arch Linux.",
|
|
1153
|
+
description="[CONFIG] Parse and analyze makepkg.conf. Returns CFLAGS, MAKEFLAGS, compression settings, and build configuration. Only works on Arch Linux. Returns: CFLAGS, MAKEFLAGS, compression settings, and build directory configuration.",
|
|
1227
1154
|
inputSchema={
|
|
1228
1155
|
"type": "object",
|
|
1229
1156
|
"properties": {}
|
|
@@ -1233,7 +1160,7 @@ async def list_tools() -> list[Tool]:
|
|
|
1233
1160
|
|
|
1234
1161
|
Tool(
|
|
1235
1162
|
name="check_ignored_packages",
|
|
1236
|
-
description="[CONFIG] List packages ignored in updates from pacman.conf. Warns if critical system packages are ignored. Only works on Arch Linux.",
|
|
1163
|
+
description="[CONFIG] List packages ignored in updates from pacman.conf. Warns if critical system packages are ignored. Only works on Arch Linux. Use case: See which packages are in IgnorePkg/IgnoreGroup to understand why they don't update.",
|
|
1237
1164
|
inputSchema={
|
|
1238
1165
|
"type": "object",
|
|
1239
1166
|
"properties": {}
|
|
@@ -1243,7 +1170,7 @@ async def list_tools() -> list[Tool]:
|
|
|
1243
1170
|
|
|
1244
1171
|
Tool(
|
|
1245
1172
|
name="get_parallel_downloads_setting",
|
|
1246
|
-
description="[CONFIG] Get parallel downloads configuration from pacman.conf and provide recommendations. Only works on Arch Linux.",
|
|
1173
|
+
description="[CONFIG] Get parallel downloads configuration from pacman.conf and provide recommendations. Only works on Arch Linux. Example: Returns current ParallelDownloads value (default=5) from pacman.conf.",
|
|
1247
1174
|
inputSchema={
|
|
1248
1175
|
"type": "object",
|
|
1249
1176
|
"properties": {}
|
|
@@ -1253,7 +1180,7 @@ async def list_tools() -> list[Tool]:
|
|
|
1253
1180
|
|
|
1254
1181
|
Tool(
|
|
1255
1182
|
name="check_database_freshness",
|
|
1256
|
-
description="[MAINTENANCE] Check when package databases were last synchronized. Warns if databases are stale (> 24 hours). Only works on Arch Linux.",
|
|
1183
|
+
description="[MAINTENANCE] Check when package databases were last synchronized. Warns if databases are stale (> 24 hours). Only works on Arch Linux. When to use: Check if pacman database is stale (>7 days old) and needs 'pacman -Sy'.",
|
|
1257
1184
|
inputSchema={
|
|
1258
1185
|
"type": "object",
|
|
1259
1186
|
"properties": {}
|
|
@@ -1263,7 +1190,7 @@ async def list_tools() -> list[Tool]:
|
|
|
1263
1190
|
|
|
1264
1191
|
Tool(
|
|
1265
1192
|
name="run_system_health_check",
|
|
1266
|
-
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.",
|
|
1193
|
+
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. Comprehensive check: Updates available, disk space, failed services, database freshness, orphans, and critical news.",
|
|
1267
1194
|
inputSchema={
|
|
1268
1195
|
"type": "object",
|
|
1269
1196
|
"properties": {}
|
|
@@ -1334,66 +1261,36 @@ async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent |
|
|
|
1334
1261
|
return [TextContent(type="text", text=json.dumps(result, indent=2))]
|
|
1335
1262
|
|
|
1336
1263
|
# Package Removal Tools
|
|
1337
|
-
elif name == "
|
|
1264
|
+
elif name == "remove_packages":
|
|
1338
1265
|
if not IS_ARCH:
|
|
1339
|
-
return [TextContent(type="text", text=create_platform_error_message("
|
|
1266
|
+
return [TextContent(type="text", text=create_platform_error_message("remove_packages"))]
|
|
1340
1267
|
|
|
1341
|
-
|
|
1268
|
+
packages = arguments["packages"]
|
|
1342
1269
|
remove_dependencies = arguments.get("remove_dependencies", False)
|
|
1343
1270
|
force = arguments.get("force", False)
|
|
1344
|
-
result = await
|
|
1345
|
-
return [TextContent(type="text", text=json.dumps(result, indent=2))]
|
|
1346
|
-
|
|
1347
|
-
elif name == "remove_packages_batch":
|
|
1348
|
-
if not IS_ARCH:
|
|
1349
|
-
return [TextContent(type="text", text=create_platform_error_message("remove_packages_batch"))]
|
|
1350
|
-
|
|
1351
|
-
package_names = arguments["package_names"]
|
|
1352
|
-
remove_dependencies = arguments.get("remove_dependencies", False)
|
|
1353
|
-
result = await remove_packages_batch(package_names, remove_dependencies)
|
|
1271
|
+
result = await remove_packages(packages, remove_dependencies, force)
|
|
1354
1272
|
return [TextContent(type="text", text=json.dumps(result, indent=2))]
|
|
1355
1273
|
|
|
1356
1274
|
# Orphan Package Management
|
|
1357
|
-
elif name == "
|
|
1358
|
-
if not IS_ARCH:
|
|
1359
|
-
return [TextContent(type="text", text=create_platform_error_message("list_orphan_packages"))]
|
|
1360
|
-
|
|
1361
|
-
result = await list_orphan_packages()
|
|
1362
|
-
return [TextContent(type="text", text=json.dumps(result, indent=2))]
|
|
1363
|
-
|
|
1364
|
-
elif name == "remove_orphans":
|
|
1275
|
+
elif name == "manage_orphans":
|
|
1365
1276
|
if not IS_ARCH:
|
|
1366
|
-
return [TextContent(type="text", text=create_platform_error_message("
|
|
1277
|
+
return [TextContent(type="text", text=create_platform_error_message("manage_orphans"))]
|
|
1367
1278
|
|
|
1279
|
+
action = arguments["action"]
|
|
1368
1280
|
dry_run = arguments.get("dry_run", True)
|
|
1369
1281
|
exclude = arguments.get("exclude", None)
|
|
1370
|
-
result = await
|
|
1282
|
+
result = await manage_orphans(action, dry_run, exclude)
|
|
1371
1283
|
return [TextContent(type="text", text=json.dumps(result, indent=2))]
|
|
1372
1284
|
|
|
1373
|
-
#
|
|
1374
|
-
elif name == "
|
|
1285
|
+
# File Ownership Query
|
|
1286
|
+
elif name == "query_file_ownership":
|
|
1375
1287
|
if not IS_ARCH:
|
|
1376
|
-
return [TextContent(type="text", text=create_platform_error_message("
|
|
1288
|
+
return [TextContent(type="text", text=create_platform_error_message("query_file_ownership"))]
|
|
1377
1289
|
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
return [TextContent(type="text", text=json.dumps(result, indent=2))]
|
|
1381
|
-
|
|
1382
|
-
elif name == "list_package_files":
|
|
1383
|
-
if not IS_ARCH:
|
|
1384
|
-
return [TextContent(type="text", text=create_platform_error_message("list_package_files"))]
|
|
1385
|
-
|
|
1386
|
-
package_name = arguments["package_name"]
|
|
1290
|
+
query = arguments["query"]
|
|
1291
|
+
mode = arguments["mode"]
|
|
1387
1292
|
filter_pattern = arguments.get("filter_pattern", None)
|
|
1388
|
-
result = await
|
|
1389
|
-
return [TextContent(type="text", text=json.dumps(result, indent=2))]
|
|
1390
|
-
|
|
1391
|
-
elif name == "search_package_files":
|
|
1392
|
-
if not IS_ARCH:
|
|
1393
|
-
return [TextContent(type="text", text=create_platform_error_message("search_package_files"))]
|
|
1394
|
-
|
|
1395
|
-
filename_pattern = arguments["filename_pattern"]
|
|
1396
|
-
result = await search_package_files(filename_pattern)
|
|
1293
|
+
result = await query_file_ownership(query, mode, filter_pattern)
|
|
1397
1294
|
return [TextContent(type="text", text=json.dumps(result, indent=2))]
|
|
1398
1295
|
|
|
1399
1296
|
# Package Verification
|
|
@@ -1423,27 +1320,13 @@ async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent |
|
|
|
1423
1320
|
return [TextContent(type="text", text=json.dumps(result, indent=2))]
|
|
1424
1321
|
|
|
1425
1322
|
# Install Reason Management
|
|
1426
|
-
elif name == "
|
|
1427
|
-
if not IS_ARCH:
|
|
1428
|
-
return [TextContent(type="text", text=create_platform_error_message("list_explicit_packages"))]
|
|
1429
|
-
|
|
1430
|
-
result = await list_explicit_packages()
|
|
1431
|
-
return [TextContent(type="text", text=json.dumps(result, indent=2))]
|
|
1432
|
-
|
|
1433
|
-
elif name == "mark_as_explicit":
|
|
1323
|
+
elif name == "manage_install_reason":
|
|
1434
1324
|
if not IS_ARCH:
|
|
1435
|
-
return [TextContent(type="text", text=create_platform_error_message("
|
|
1325
|
+
return [TextContent(type="text", text=create_platform_error_message("manage_install_reason"))]
|
|
1436
1326
|
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
elif name == "mark_as_dependency":
|
|
1442
|
-
if not IS_ARCH:
|
|
1443
|
-
return [TextContent(type="text", text=create_platform_error_message("mark_as_dependency"))]
|
|
1444
|
-
|
|
1445
|
-
package_name = arguments["package_name"]
|
|
1446
|
-
result = await mark_as_dependency(package_name)
|
|
1327
|
+
action = arguments["action"]
|
|
1328
|
+
package_name = arguments.get("package_name", None)
|
|
1329
|
+
result = await manage_install_reason(action, package_name)
|
|
1447
1330
|
return [TextContent(type="text", text=json.dumps(result, indent=2))]
|
|
1448
1331
|
|
|
1449
1332
|
# System Diagnostic Tools
|
|
@@ -2107,7 +1990,7 @@ paru -S {package_name} # or yay -S {package_name}
|
|
|
2107
1990
|
text=f"""Please perform a comprehensive system cleanup:
|
|
2108
1991
|
|
|
2109
1992
|
1. **Check Orphaned Packages**:
|
|
2110
|
-
- Run
|
|
1993
|
+
- Run manage_orphans with action='list'
|
|
2111
1994
|
- Review the list for packages that can be safely removed
|
|
2112
1995
|
{' - Be aggressive: remove all orphans unless critical' if aggressive else ' - Be conservative: keep packages that might be useful'}
|
|
2113
1996
|
|
|
@@ -2303,7 +2186,7 @@ Be detailed and provide specific mirror URLs and configuration commands."""
|
|
|
2303
2186
|
- Identify any package operation failures
|
|
2304
2187
|
|
|
2305
2188
|
5. **Package Integrity**:
|
|
2306
|
-
- Run
|
|
2189
|
+
- Run manage_orphans with action='list'
|
|
2307
2190
|
- Count orphaned packages and space used
|
|
2308
2191
|
- Suggest running verify_package_integrity on critical packages
|
|
2309
2192
|
|
|
@@ -8,17 +8,19 @@ import logging
|
|
|
8
8
|
from typing import Dict, Any
|
|
9
9
|
|
|
10
10
|
from .utils import IS_ARCH
|
|
11
|
-
from . import (
|
|
11
|
+
from .system import (
|
|
12
12
|
get_system_info,
|
|
13
13
|
check_disk_space,
|
|
14
14
|
check_failed_services,
|
|
15
|
-
get_pacman_cache_stats
|
|
15
|
+
get_pacman_cache_stats
|
|
16
|
+
)
|
|
17
|
+
from .pacman import (
|
|
16
18
|
check_updates_dry_run,
|
|
17
|
-
check_critical_news,
|
|
18
19
|
list_orphan_packages,
|
|
19
|
-
check_database_freshness
|
|
20
|
-
check_mirrorlist_health
|
|
20
|
+
check_database_freshness
|
|
21
21
|
)
|
|
22
|
+
from .news import check_critical_news
|
|
23
|
+
from .mirrors import check_mirrorlist_health
|
|
22
24
|
|
|
23
25
|
logger = logging.getLogger(__name__)
|
|
24
26
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: arch-ops-server
|
|
3
|
-
Version: 3.3.
|
|
3
|
+
Version: 3.3.2
|
|
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
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
arch_ops_server/__init__.py,sha256=
|
|
1
|
+
arch_ops_server/__init__.py,sha256=1N7UkiBwBxfPve-DXzSRkg1oOgWeZK24XPlh6Mh11W0,4539
|
|
2
2
|
arch_ops_server/aur.py,sha256=poYbh2DW7I1tZfCeNp_7e10fh9ZZx8HTnYZnKKZtflQ,49808
|
|
3
3
|
arch_ops_server/config.py,sha256=4mtpS28vXSMeEVGrTWTMwZEzgIyfl0oCAYEzF7SKxE8,11076
|
|
4
4
|
arch_ops_server/http_server.py,sha256=wZ3hY6o6EftbN1OZiTUau7861LB9ihKWap6gevev_No,31810
|
|
5
5
|
arch_ops_server/logs.py,sha256=qWExDvluHmQvbZHu87veQxMnuMK8BNLBYBppZJlemEc,10558
|
|
6
6
|
arch_ops_server/mirrors.py,sha256=Evt-g20cMOTZQl9FbbkbklFd0gKWz-I7vVNrmyQO19U,13403
|
|
7
7
|
arch_ops_server/news.py,sha256=E97eASR24tq_EaVDYuamIoBl4a7QtBkpscOaUPuU0W4,9359
|
|
8
|
-
arch_ops_server/pacman.py,sha256=
|
|
8
|
+
arch_ops_server/pacman.py,sha256=y0-0wrGx2bWjLyBRyLYOz1ogtQnH2RYjISC-MCJOB-k,46860
|
|
9
9
|
arch_ops_server/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
arch_ops_server/server.py,sha256=
|
|
10
|
+
arch_ops_server/server.py,sha256=sBkE0oaDE_bVFSMJXLQiC2owejgGMXW-soy0ME7dKGQ,89906
|
|
11
11
|
arch_ops_server/system.py,sha256=JfBUB3KD0veulQ-IIK8IOC8Jn6lqtLMCtlnryiL1n7w,9221
|
|
12
|
-
arch_ops_server/system_health_check.py,sha256=
|
|
12
|
+
arch_ops_server/system_health_check.py,sha256=81Li_9L_LMVhNZrFd89qhdXcbt17hFM7YHOoy903xuc,7254
|
|
13
13
|
arch_ops_server/tool_metadata.py,sha256=Z0ZhtS1bxo9T_erJlGx9Xf0fKk4oZ0L6UQ8gJu7WEcA,20468
|
|
14
14
|
arch_ops_server/utils.py,sha256=po7MVqCx-hsdx-lOgs7uGicjoUVMf6HvuNNYl2qyFH0,10112
|
|
15
15
|
arch_ops_server/wiki.py,sha256=XB_emMGXYF3Vn5likRICkGOa72YDZvOhtZBgp_d1gg8,7350
|
|
16
|
-
arch_ops_server-3.3.
|
|
17
|
-
arch_ops_server-3.3.
|
|
18
|
-
arch_ops_server-3.3.
|
|
19
|
-
arch_ops_server-3.3.
|
|
16
|
+
arch_ops_server-3.3.2.dist-info/WHEEL,sha256=5DEXXimM34_d4Gx1AuF9ysMr1_maoEtGKjaILM3s4w4,80
|
|
17
|
+
arch_ops_server-3.3.2.dist-info/entry_points.txt,sha256=ZS2crFEqE9TteC4j2HmYS1wKvoBOCCXT2FJXJW5C4-E,117
|
|
18
|
+
arch_ops_server-3.3.2.dist-info/METADATA,sha256=EuVUE9MwTQo75MK_CrfdI8FAGoqmn7pGbqVAppQR-FE,11356
|
|
19
|
+
arch_ops_server-3.3.2.dist-info/RECORD,,
|
|
File without changes
|