Technical overview of the Arch MCP Server implementation following the Arch Way principles.
Design Philosophy
This server embodies the Arch Way principles in its implementation.
Minimalism No unnecessary abstractions or bloat. Every function serves a clear purpose with clean, readable code. The entire codebase is under 3,000 lines - easy to audit and understand.
Correctness Comprehensive error handling at every layer, full type hints, and extensive logging for debugging. async def get_wiki_page ( title : str ) -> str :
"""Type hints ensure correctness"""
try :
# Proper error handling
return await _fetch_via_api(title)
except HTTPError as e:
logger.error( f "Failed: { e } " )
raise
Transparency Every module is well-documented with clear function signatures, docstrings, and inline comments. No magic - you can read the source and understand exactly what’s happening.
User-Centricity Assumes competent users. Provides detailed information and warnings, but doesn’t prevent advanced usage. AUR warnings inform users of risks but don’t block access - you decide.
Pragmatism Hybrid local/remote approach: uses fast local queries on Arch, falls back to remote APIs elsewhere. if IS_ARCH and has_pacman():
return await _local_query()
else :
return await _remote_api()
Simplicity Standard library and minimal dependencies. No complex frameworks or heavy abstractions. Dependencies: httpx, beautifulsoup4, markdownify, mcp
System Architecture
┌─────────────────────────────────────────────────────────┐
│ MCP Client (Claude, Cursor etc.) │
└───────────────────────┬─────────────────────────────────┘
│ Transport Layer
│ • STDIO (stdin/stdout)
│ • HTTP/SSE (Server-Sent Events)
┌───────────────────────▼─────────────────────────────────┐
│ arch_ops_server.py / http_server.py │
│ (MCP Server Core) │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Resources Tools Prompts│ │
│ │ - archwiki:// - search_archwiki - trbl │ │
│ │ - aur:// - search_aur - audit │ │
│ │ - get_official_pkg - deps │ │
│ │ - check_updates │ │
│ │ - analyze_pkgbuild │ │
│ └─────────────────────────────────────────────────┘ │
└───────────────────────┬─────────────────────────────────┘
│ Function Calls
┌───────────────────────▼─────────────────────────────────┐
│ Module Layer (src/arch_ops_server/) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐│
│ │ wiki.py │ │ aur.py │ │pacman.py │ │ system.py││
│ │ │ │ │ │ │ │ ││
│ │MediaWiki │ │ AUR RPC │ │ Hybrid │ │Monitoring││
│ │API + BS4 │ │ v5 │ │Local/API │ │& Diag. ││
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘│
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐│
│ │ news.py │ │ logs.py │ │mirrors.py│ │ config.py││
│ │ │ │ │ │ │ │ ││
│ │RSS Feed │ │Transaction│ │ Mirror │ │ Config ││
│ │ Parser │ │ History │ │ Manager │ │ Parser ││
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘│
│ ┌──────────┐ │
│ │ utils.py │ │
│ │Platform │ │
│ │Detection │ │
│ └──────────┘ │
└───────────────────────┬─────────────────────────────────┘
│ Network/System Calls
┌───────────────────────▼─────────────────────────────────┐
│ External Services & Local System │
│ ┌──────────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ Arch Wiki │ │ AUR │ │ Local pacman │ │
│ │ wiki.arch.. │ │ aur.a.. │ │ (if on Arch) │ │
│ └──────────────┘ └──────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────────────┘
Module Breakdown
Main Entry Point (__init__.py and server.py)
__init__.py Responsibilities:
Package initialization
Function exports
Async main() entry point
STDIO transport setup
server.py Responsibilities:
Responsibilities:
MCP protocol implementation
Resource URI handling
Tool invocation routing
Prompt template management
STDIO transport setup
Key Features:
Async operation for all network calls
URI parsing for resources
JSON serialization of responses
Error propagation from modules
HTTP Server Module (http_server.py)
New in v3.1.0: HTTP/SSE transport support for containerized deployments.
Purpose:
Alternative transport to STDIO for web-based clients
Server-Sent Events (SSE) for real-time communication
Containerized deployment support (Docker, Smithery)
Health check endpoint for monitoring
Entry Points:
arch-ops-server - STDIO transport (default)
arch-ops-server-http - HTTP/SSE transport
Configuration:
# Install with HTTP extras
uv pip install "arch-ops-server[http]"
# Run HTTP server
arch-ops-server-http
# Custom port
PORT = 8000 arch-ops-server-http
Dependencies:
starlette - ASGI framework for HTTP routing
uvicorn - ASGI server for production
mcp.server.sse - SSE transport implementation
Tool Metadata System (tool_metadata.py)
New in v3.1.0: Structured tool organization and relationships.
Purpose:
Categorizes all 22 tools into 9 logical groups
Defines tool relationships and workflows
Provides discoverability metadata
Enables intelligent tool suggestions
Categories:
CATEGORIES = {
"discovery" : "🔍 Discovery & Information" ,
"lifecycle" : "📦 Package Lifecycle" ,
"maintenance" : "🔧 Package Maintenance" ,
"organization" : "📁 File Organization" ,
"security" : "🔒 Security Analysis" ,
"monitoring" : "📊 System Monitoring" ,
"history" : "📜 Transaction History" ,
"mirrors" : "🌐 Mirror Management" ,
"config" : "⚙️ Configuration"
}
Metadata Fields:
category - Logical grouping
platform - “any”, “arch”, or “systemd”
permission - “read” or “write”
workflow - Usage context (research, installation, cleanup, etc.)
related_tools - Tools commonly used together
prerequisite_tools - Tools to run first
Helper Functions:
get_tools_by_category(category) -> List[ str ]
get_tools_by_platform(platform) -> List[ str ]
get_tools_by_permission(permission) -> List[ str ]
get_related_tools(tool_name) -> List[ str ]
get_prerequisite_tools(tool_name) -> List[ str ]
get_workflow_tools(workflow) -> List[ str ]
get_tool_statistics() -> dict
Use Cases:
Auto-suggest related tools to users
Build guided workflows
Filter by platform/permission
Generate documentation
Analyze tool coverage
Utilities (utils.py)
Core helper functions for platform detection, command execution, and error handling.
Platform Detection
Safe Command Execution
AUR Warning Wrapper
Error Response Format
def is_arch_linux () -> bool :
"""
Detect if running on Arch Linux.
Checks both /etc/arch-release and /etc/os-release
for maximum compatibility.
Returns:
True if Arch Linux, False otherwise
"""
if Path( "/etc/arch-release" ).exists():
return True
try :
with open ( "/etc/os-release" ) as f:
return "arch" in f.read().lower()
except FileNotFoundError :
return False
async def run_command (
cmd : list[ str ],
timeout : int = 10 ,
check : bool = True
) -> tuple[ int , str , str ]:
"""
Execute command with timeout protection.
Args:
cmd: Command and arguments as list
timeout: Max execution time in seconds
check: Raise exception on non-zero exit
Returns:
(exit_code, stdout, stderr)
Raises:
TimeoutError: Command exceeded timeout
subprocess.CalledProcessError: Non-zero exit (if check=True)
"""
process = await asyncio.create_subprocess_exec(
* cmd,
stdout = asyncio.subprocess. PIPE ,
stderr = asyncio.subprocess. PIPE
)
try :
stdout, stderr = await asyncio.wait_for(
process.communicate(),
timeout = timeout
)
except asyncio.TimeoutError:
process.kill()
raise TimeoutError ( f "Command timed out: { cmd } " )
return process.returncode, stdout.decode(), stderr.decode()
def add_aur_warning ( data : dict ) -> dict :
"""
Wrap AUR data with safety warnings.
Adds prominent warning message about AUR packages
being user-produced content that should be reviewed.
Args:
data: AUR package data
Returns:
Data with added warning field
"""
return {
** data,
"warning" : (
"⚠️ AUR packages are user-produced content. "
"Any use of the provided files is at your own risk. "
"Always review PKGBUILDs before installing."
)
}
def create_error_response (
error_type : str ,
message : str ,
details : str | None = None
) -> dict :
"""
Create standardized error response for MCP clients.
Ensures consistent error format across all modules
for better client-side handling.
Args:
error_type: Category (NotFound, TimeoutError, etc.)
message: Human-readable error message
details: Optional additional context
Returns:
Structured error dict
"""
return {
"error" : True ,
"type" : error_type,
"message" : message,
"details" : details
}
All functions use type hints and comprehensive docstrings following Google style.
Arch Wiki Interface (wiki.py)
Manages Arch Wiki searches and page retrieval:
search_wiki(query: str ) -> List[ str ]
└─ > MediaWiki API opensearch
└─ > Returns [titles, descriptions, urls]
get_wiki_page(title: str ) -> str
├─ > Try: _fetch_via_api()
│ └─ > MediaWiki API parse action
└─ > Fallback: _fetch_via_scraping()
└─ > BeautifulSoup on HTML
└─ > Extract #bodyContent div
└─ > Convert to Markdown (markdownify)
API Endpoints:
https://wiki.archlinux.org/api.php
Direct page URLs for scraping fallback
Error Handling:
Timeouts (10s default)
HTTP errors with status codes
Missing pages (404)
API errors in response JSON
AUR RPC Interface (aur.py)
Handles AUR package operations and security analysis:
search_aur(query: str ) -> dict
└─ > GET / rpc ? v = 5 & type = search & arg = {query}
└─ > Format package list
└─ > add_aur_warning()
get_aur_info(package: str ) -> dict
└─ > GET / rpc ? v = 5 & type = info & arg[] = {package}
└─ > Format detailed package info
└─ > add_aur_warning()
get_pkgbuild(package: str ) -> str
└─ > GET / cgit / aur.git / plain / PKGBUILD ? h = {package}
└─ > Raw PKGBUILD text
audit_package_security(action: str , ** kwargs) -> dict
└─ > action = 'pkgbuild_analysis' : Regex pattern matching for red flags
│ ├─ > Dangerous: rm - rf / , dd, fork bombs
│ ├─ > Suspicious: base64, eval , curl | sh
│ └─ > Warnings: chmod 777 , binary downloads
└─ > action= 'metadata_risk' : Evaluate trustworthiness
├─ > Vote count validation
├─ > Maintainer verification
└─ > Package age and update frequency
API Endpoints:
https://aur.archlinux.org/rpc
https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD
Official Repository Interface (pacman.py)
Hybrid local/remote access to official packages and comprehensive package management:
get_official_package_info(package: str ) -> dict
├─ > If IS_ARCH and pacman exists:
│ └─ > run_command([ "pacman" , "-Si" , package])
│ └─ > _parse_pacman_output()
└─ > Else:
└─ > GET archlinux.org / packages / search / json /
└─ > Parse API response
check_updates_dry_run() -> str
├─ > Verify IS_ARCH
├─ > Check checkupdates command exists
└─ > run_command([ "checkupdates" ])
└─ > _parse_checkupdates_output()
# Package Lifecycle (consolidated)
remove_packages(packages: str | list , ... )
# Package Maintenance
manage_orphans(action: str , ... )
manage_install_reason(action: str , ... )
# Package Discovery
query_file_ownership(query: str , mode: str , ... )
verify_package_integrity(package: str , ... )
# Package Groups
manage_groups(action: str , ... )
# Database Management
check_database_freshness()
Hybrid Approach:
On Arch : Fast local queries, offline-capable
Remote : API-based, works anywhere
System Monitoring (system.py)
System health and diagnostics:
get_system_info() -> dict
└─ > Platform info, kernel, memory, uptime
analyze_storage(action: str ) -> dict
├─ > action = 'disk_usage' : Disk usage for / , / home, / var with warnings
└─ > action= 'cache_stats' : Cache size, package count, age analysis
diagnose_system(action: str ) -> dict
├─ > action= 'failed_services' : systemctl -- failed
└─ > action= 'boot_logs' : journalctl - b
run_system_health_check() -> dict
└─ > Comprehensive: updates, disk, services, orphans, database, news
News Integration (news.py)
Arch Linux news feed parsing:
fetch_news(action: str , ... ) -> dict
├─ > action = 'latest' : Parse RSS from archlinux.org / feeds / news /
├─ > action = 'critical' : Filter news requiring manual intervention
└─ > action = 'since_update' : Compare news timestamps with last pacman - Syu
Transaction Logs (logs.py)
Pacman transaction history:
query_package_history(query_type: str , ... ) -> dict
├─ > query_type = 'all' : Recent transactions
├─ > query_type = 'package' : Specific package install / upgrade history
├─ > query_type = 'failures' : Failed operations
└─ > query_type = 'sync' : Database sync history
Mirror Management (mirrors.py)
Repository mirror testing and optimization:
optimize_mirrors(action: str , ... ) -> dict
├─ > action = 'status' : Parse / etc / pacman.d / mirrorlist
├─ > action = 'test' : Latency and throughput testing
├─ > action = 'suggest' : Query mirror status API
└─ > action = 'health' : Validate mirror configuration
Configuration Parsing (config.py)
System configuration analysis:
analyze_pacman_conf(focus: str = "full" ) -> dict
├─ > focus = 'full' : Parse / etc / pacman.conf
├─ > focus = 'ignored_packages' : List packages in IgnorePkg
└─ > focus = 'parallel_downloads' : Extract ParallelDownloads value
analyze_makepkg_conf() -> dict
└─ > Parse / etc / makepkg.conf
Data Flow Examples
Example 1: Reading an Arch Wiki Page
Example 2: Auditing an AUR Package
Error Handling Strategy
Graceful Degradation
wiki.get_wiki_page(title):
Try: API fetch
├─ Success → return content
└─ Fail → Try scraping
├─ Success → return content
└─ Fail → raise ValueError
pacman.get_official_package_info(pkg):
If on Arch:
Try: Local pacman
├─ Success → return info
└─ Fail → Try remote API
Else:
Try: Remote API
├─ Success → return info
└─ Fail → return error_response
Error Response Format
All errors follow consistent structure:
{
"error" : true ,
"type" : "ErrorType" ,
"message" : "Human-readable message" ,
"details" : "Optional additional context"
}
Error Types:
NotFound - Resource doesn’t exist
TimeoutError - Network timeout
HTTPError - HTTP status error
NotSupported - Feature unavailable on platform
CommandNotFound - Required command missing
RateLimitError - API rate limit exceeded
Concurrency Model
Async/Await Throughout
All network and subprocess operations are async for non-blocking I/O:
# Server level
async def read_resource ( uri : str ) -> str
# Module level
async def get_wiki_page(title: str ) -> str
async def search_aur(query: str ) -> dict
async def run_command(cmd: list ) -> tuple
# Client usage
result = await wiki.search_wiki( "systemd" )
Benefits:
Non-blocking I/O
Concurrent tool calls possible
Responsive server
Timeout support built-in
HTTP Client Management
Uses httpx.AsyncClient with context managers:
async with httpx.AsyncClient( timeout = 10.0 ) as client:
response = await client.get(url)
Features:
Automatic connection pooling
Timeout enforcement
Proper cleanup
HTTP/2 support
Security Considerations
AUR Safety (Defense in Depth)
Multi-layered security approach for AUR package handling.
Warning Metadata
Every AUR response includes prominent warnings: {
"package" : "..." ,
"warning" : "⚠️ AUR packages are user-produced content. Always review before installing."
}
Warnings are added automatically by add_aur_warning() utility function.
PKGBUILD Analysis
Automated scanning for 50+ threat patterns:
🔴 Critical: rm -rf /, fork bombs, kernel module loading
🟠 Dangerous: dd, mkfs, direct /dev access
🟡 Suspicious: curl|sh, eval, base64 pipes
Pattern matching has limitations - see below.
Metadata Evaluation
Display community trust indicators: {
"votes" : 245 , # Popularity
"popularity" : 8.5 , # Weighted score
"maintainer" : "..." , # Who maintains it
"last_modified" : "..." , # Recent activity
"out_of_date" : false # Maintenance status
}
Manual Review Encouragement
Tools facilitate human review:
aur://package/pkgbuild - Easy PKGBUILD access
Formatted, syntax-highlighted display
Side-by-side with analysis results
The AI assistant can explain suspicious patterns in plain English.
Official First Policy
Check official repos before AUR: # install_package_secure workflow
1 . get_official_package_info() # Try official first
2 . if not found:
3 . analyze_aur_package() # Then check AUR
Known Limitations:
❌ Pattern matching can’t catch all malicious code
❌ Obfuscation techniques can bypass detection
❌ Zero-day exploits won’t be detected
✅ User judgment is always required
Never blindly trust automated scans!
Command Execution
Only safe read-only commands:
pacman -Si - Query package info
checkupdates - Check for updates (no installation)
Protections:
Timeout enforcement (default 10s)
No shell=True (prevents shell injection)
Whitelist of allowed commands
Platform checks before execution
Network Safety
Timeout limits - All requests have timeouts
HTTPS only - No plaintext HTTP
Rate limiting - Handle 429 responses
Input validation - Sanitize user inputs
Performance Optimizations
Caching Strategy
Current: No caching (always live data)
Rationale: Rolling release means data changes frequently
Future: Consider time-based caching:
Wiki pages: 1 hour
Package info: 5 minutes
AUR metadata: 10 minutes
Request Efficiency
Single API calls - No unnecessary round trips
Async operations - Concurrent requests possible
Connection pooling - httpx manages connections
Timeout limits - Don’t wait forever
Testing Strategy
Functional Tests
Basic tests verify core functionality:
uv run python test_server.py
Tests cover:
Wiki search and page retrieval
AUR search and PKGBUILD fetch
Official package lookup
Platform detection
Integration Testing
Use MCP Inspector for interactive testing:
Manual Testing Checklist
Extension Points
Adding New Tools
Create async function in appropriate module
Export from __init__.py
Add @server.tool() decorator in main file
Update list_tools() with schema
Add handler in call_tool()
Document in README and examples
Adding New Resources
Define URI scheme
Add parsing in read_resource()
Implement fetch logic in module
Add example to list_resources()
Document usage
Adding New Prompts
Design workflow
Add @server.prompt() decorator
Implement in get_prompt()
Add to list_prompts()
Create example in documentation
Future Enhancements
Planned Features
Potential Improvements
Contributing
Want to contribute? See the Contributing Guide for:
Development setup and testing
Code standards and best practices
Pull request process
Feature contribution guidelines
References
Built with ❤️ following the Arch Way.