Skip to content

Formatters

formatters

Shared output formatters for tool results.

This module provides functions to format parsed data into human-readable strings for tool output.

format_audit_logs

format_audit_logs(stdout: str, lines_count: int) -> str

Format audit logs output.

Parameters:

Name Type Description Default
stdout str

Raw output from tail on audit.log.

required
lines_count int

Number of log lines.

required

Returns:

Type Description
str

Formatted string representation.

Source code in src/linux_mcp_server/formatters.py
def format_audit_logs(stdout: str, lines_count: int) -> str:
    """Format audit logs output.

    Args:
        stdout: Raw output from tail on audit.log.
        lines_count: Number of log lines.

    Returns:
        Formatted string representation.
    """
    lines = [f"=== Audit Logs (last {lines_count} entries) ===\n"]
    lines.append(stdout)
    return "\n".join(lines)

format_block_devices

format_block_devices(
    stdout: str, disk_io: str | None = None
) -> str

Format block devices output.

Parameters:

Name Type Description Default
stdout str

Raw output from lsblk.

required
disk_io str | None

Optional disk I/O statistics.

None

Returns:

Type Description
str

Formatted string representation.

Source code in src/linux_mcp_server/formatters.py
def format_block_devices(stdout: str, disk_io: str | None = None) -> str:
    """Format block devices output.

    Args:
        stdout: Raw output from lsblk.
        disk_io: Optional disk I/O statistics.

    Returns:
        Formatted string representation.
    """
    lines = ["=== Block Devices ===\n"]
    lines.append(stdout)

    if disk_io:
        lines.append("\n=== Disk I/O Statistics (per disk) ===")
        lines.append(disk_io)

    return "\n".join(lines)

format_cpu_info

format_cpu_info(info: CpuInfo) -> str

Format CPU information into a readable string.

Parameters:

Name Type Description Default
info CpuInfo

CpuInfo object.

required

Returns:

Type Description
str

Formatted string representation.

Source code in src/linux_mcp_server/formatters.py
def format_cpu_info(info: CpuInfo) -> str:
    """Format CPU information into a readable string.

    Args:
        info: CpuInfo object.

    Returns:
        Formatted string representation.
    """
    lines = []

    if info.model:
        lines.append(f"CPU Model: {info.model}")
    if info.physical_cores:
        lines.append(f"CPU Physical Cores: {info.physical_cores}")
    if info.logical_cores:
        lines.append(f"CPU Logical Cores (threads): {info.logical_cores}")
    if info.frequency_mhz:
        lines.append(f"CPU Frequency: Current={info.frequency_mhz:.2f}MHz")

    if info.load_avg_1m or info.load_avg_5m or info.load_avg_15m:
        lines.append(
            f"\nLoad Average (1m, 5m, 15m): {info.load_avg_1m:.2f}, {info.load_avg_5m:.2f}, {info.load_avg_15m:.2f}"
        )

    if info.cpu_line:
        lines.append(f"\n{info.cpu_line}")

    return "\n".join(lines)

format_directory_listing

format_directory_listing(
    entries: list[NodeEntry],
    path: str,
    sort_by: str,
    reverse: bool = False,
) -> str

Format directory listing into a readable string.

Parameters:

Name Type Description Default
entries list[NodeEntry]

List of NodeEntry objects.

required
path str

Path that was listed.

required
sort_by str

Sort field used.

required
reverse bool

Whether the sort was reversed.

False

Returns:

Type Description
str

Formatted string representation.

Source code in src/linux_mcp_server/formatters.py
def format_directory_listing(
    entries: list[NodeEntry],
    path: str,
    sort_by: str,
    reverse: bool = False,
) -> str:
    """Format directory listing into a readable string.

    Args:
        entries: List of NodeEntry objects.
        path: Path that was listed.
        sort_by: Sort field used.
        reverse: Whether the sort was reversed.

    Returns:
        Formatted string representation.
    """
    lines = [f"=== Directories in {path} ===\n"]

    # Sort entries
    if sort_by == "size":
        sorted_entries = sorted(entries, key=lambda e: e.size, reverse=reverse)
    elif sort_by == "modified":
        sorted_entries = sorted(entries, key=lambda e: e.modified, reverse=reverse)
    else:
        sorted_entries = sorted(entries, key=lambda e: e.name.lower(), reverse=reverse)

    for entry in sorted_entries:
        if sort_by == "size":
            lines.append(f"{format_bytes(entry.size):>12}  {entry.name}")
        elif sort_by == "modified":
            dt = datetime.fromtimestamp(entry.modified)
            lines.append(f"{dt.strftime('%Y-%m-%d %H:%M:%S')}  {entry.name}")
        else:
            lines.append(f"  {entry.name}")

    lines.append(f"\nTotal directories: {len(entries)}")
    return "\n".join(lines)

format_disk_usage

format_disk_usage(
    stdout: str, disk_io: str | None = None
) -> str

Format disk usage output.

Parameters:

Name Type Description Default
stdout str

Raw output from df command.

required
disk_io str | None

Optional disk I/O statistics.

None

Returns:

Type Description
str

Formatted string representation.

Source code in src/linux_mcp_server/formatters.py
def format_disk_usage(stdout: str, disk_io: str | None = None) -> str:
    """Format disk usage output.

    Args:
        stdout: Raw output from df command.
        disk_io: Optional disk I/O statistics.

    Returns:
        Formatted string representation.
    """
    lines = ["=== Filesystem Usage ===\n"]
    lines.append(stdout)

    if disk_io:
        lines.append("\n=== Disk I/O Statistics (since boot) ===")
        lines.append(disk_io)

    return "\n".join(lines)

format_file_listing

format_file_listing(
    entries: list[NodeEntry],
    path: str,
    sort_by: str,
    reverse: bool = False,
) -> str

Format file listing into a readable string.

Parameters:

Name Type Description Default
entries list[NodeEntry]

List of NodeEntry objects.

required
path str

Path that was listed.

required
sort_by str

Sort field used.

required
reverse bool

Whether the sort was reversed.

False

Returns:

Type Description
str

Formatted string representation.

Source code in src/linux_mcp_server/formatters.py
def format_file_listing(
    entries: list[NodeEntry],
    path: str,
    sort_by: str,
    reverse: bool = False,
) -> str:
    """Format file listing into a readable string.

    Args:
        entries: List of NodeEntry objects.
        path: Path that was listed.
        sort_by: Sort field used.
        reverse: Whether the sort was reversed.

    Returns:
        Formatted string representation.
    """
    lines = [f"=== Files in {path} ===\n"]

    # Sort entries
    if sort_by == "size":
        sorted_entries = sorted(entries, key=lambda e: e.size, reverse=reverse)
    elif sort_by == "modified":
        sorted_entries = sorted(entries, key=lambda e: e.modified, reverse=reverse)
    else:
        sorted_entries = sorted(entries, key=lambda e: e.name.lower(), reverse=reverse)

    for entry in sorted_entries:
        if sort_by == "size":
            lines.append(f"{format_bytes(entry.size):>12}  {entry.name}")
        elif sort_by == "modified":
            dt = datetime.fromtimestamp(entry.modified)
            lines.append(f"{dt.strftime('%Y-%m-%d %H:%M:%S')}  {entry.name}")
        else:
            lines.append(f"  {entry.name}")

    lines.append(f"\nTotal files: {len(entries)}")
    return "\n".join(lines)

format_hardware_info

format_hardware_info(results: dict[str, str]) -> str

Format hardware information output.

Parameters:

Name Type Description Default
results dict[str, str]

Dictionary of command name to output.

required

Returns:

Type Description
str

Formatted string representation.

Source code in src/linux_mcp_server/formatters.py
def format_hardware_info(results: dict[str, str]) -> str:
    """Format hardware information output.

    Args:
        results: Dictionary of command name to output.

    Returns:
        Formatted string representation.
    """
    lines = ["=== Hardware Information ===\n"]

    if "lscpu" in results and results["lscpu"]:
        lines.append("=== CPU Architecture (lscpu) ===")
        lines.append(results["lscpu"])

    if "lspci" in results and results["lspci"]:
        pci_lines = results["lspci"].strip().split("\n")
        lines.append("\n=== PCI Devices ===")
        # Show first 50 devices
        for line in pci_lines[:50]:
            lines.append(line)
        if len(pci_lines) > 50:
            lines.append(f"\n... and {len(pci_lines) - 50} more PCI devices")

    if "lsusb" in results and results["lsusb"]:
        lines.append("\n\n=== USB Devices ===")
        lines.append(results["lsusb"])

    if len(lines) == 1:  # Only header
        lines.append("No hardware information tools available.")

    return "\n".join(lines)

format_journal_logs

format_journal_logs(
    stdout: str,
    lines_count: int,
    unit: str | None = None,
    priority: str | None = None,
    since: str | None = None,
) -> str

Format journal logs output.

Parameters:

Name Type Description Default
stdout str

Raw output from journalctl.

required
lines_count int

Number of log lines.

required
unit str | None

Optional unit filter.

None
priority str | None

Optional priority filter.

None
since str | None

Optional time filter.

None

Returns:

Type Description
str

Formatted string representation.

Source code in src/linux_mcp_server/formatters.py
def format_journal_logs(
    stdout: str,
    lines_count: int,
    unit: str | None = None,
    priority: str | None = None,
    since: str | None = None,
) -> str:
    """Format journal logs output.

    Args:
        stdout: Raw output from journalctl.
        lines_count: Number of log lines.
        unit: Optional unit filter.
        priority: Optional priority filter.
        since: Optional time filter.

    Returns:
        Formatted string representation.
    """
    filters = []
    if unit:
        filters.append(f"unit={unit}")
    if priority:
        filters.append(f"priority={priority}")
    if since:
        filters.append(f"since={since}")

    filter_desc = ", ".join(filters) if filters else "no filters"

    lines = [f"=== Journal Logs (last {lines_count} entries, {filter_desc}) ===\n"]
    lines.append(stdout)
    return "\n".join(lines)

format_listening_ports

format_listening_ports(
    ports: list[ListeningPort],
    header: str = "=== Listening Ports ===\n",
) -> str

Format listening ports into a readable string.

Parameters:

Name Type Description Default
ports list[ListeningPort]

List of ListeningPort objects.

required
header str

Header text for the output.

'=== Listening Ports ===\n'

Returns:

Type Description
str

Formatted string representation.

Source code in src/linux_mcp_server/formatters.py
def format_listening_ports(
    ports: list[ListeningPort],
    header: str = "=== Listening Ports ===\n",
) -> str:
    """Format listening ports into a readable string.

    Args:
        ports: List of ListeningPort objects.
        header: Header text for the output.

    Returns:
        Formatted string representation.
    """
    lines = [header]
    lines.append(f"{'Proto':<8} {'Local Address':<30} {'Status':<15} {'PID/Program'}")
    lines.append("-" * 80)

    for port in ports:
        local = f"{port.local_address}:{port.local_port}"
        lines.append(f"{port.protocol:<8} {local:<30} {'LISTEN':<15} {port.process}")

    lines.append(f"\n\nTotal listening ports: {len(ports)}")
    return "\n".join(lines)

format_log_file

format_log_file(
    stdout: str, log_path: str, lines_count: int
) -> str

Format log file output.

Parameters:

Name Type Description Default
stdout str

Raw content from log file.

required
log_path str

Path to the log file.

required
lines_count int

Number of lines read.

required

Returns:

Type Description
str

Formatted string representation.

Source code in src/linux_mcp_server/formatters.py
def format_log_file(stdout: str, log_path: str, lines_count: int) -> str:
    """Format log file output.

    Args:
        stdout: Raw content from log file.
        log_path: Path to the log file.
        lines_count: Number of lines read.

    Returns:
        Formatted string representation.
    """
    lines = [f"=== Log File: {log_path} (last {lines_count} lines) ===\n"]
    lines.append(stdout)
    return "\n".join(lines)

format_memory_info

format_memory_info(memory: SystemMemory) -> str

Format memory information into a readable string.

Parameters:

Name Type Description Default
memory SystemMemory

SystemMemory object containing RAM and swap info.

required

Returns:

Type Description
str

Formatted string representation.

Source code in src/linux_mcp_server/formatters.py
def format_memory_info(memory: SystemMemory) -> str:
    """Format memory information into a readable string.

    Args:
        memory: SystemMemory object containing RAM and swap info.

    Returns:
        Formatted string representation.
    """
    lines = []

    # RAM information
    ram = memory.ram
    ram_percent = (ram.used / ram.total * 100) if ram.total > 0 else 0

    lines.append("=== RAM Information ===")
    lines.append(f"Total: {format_bytes(ram.total)}")
    lines.append(f"Available: {format_bytes(ram.available)}")
    lines.append(f"Used: {format_bytes(ram.used)} ({ram_percent:.1f}%)")
    lines.append(f"Free: {format_bytes(ram.free)}")

    if ram.buffers:
        lines.append(f"Buffers: {format_bytes(ram.buffers)}")

    if ram.cached:
        lines.append(f"Cache: {format_bytes(ram.cached)}")

    # Swap information
    if memory.swap:
        swap = memory.swap
        swap_percent = (swap.used / swap.total * 100) if swap.total > 0 else 0

        lines.append("\n=== Swap Information ===")
        lines.append(f"Total: {format_bytes(swap.total)}")
        lines.append(f"Used: {format_bytes(swap.used)} ({swap_percent:.1f}%)")
        lines.append(f"Free: {format_bytes(swap.free)}")

    return "\n".join(lines)

format_network_connections

format_network_connections(
    connections: list[NetworkConnection],
    header: str = "=== Active Network Connections ===\n",
) -> str

Format network connections into a readable string.

Parameters:

Name Type Description Default
connections list[NetworkConnection]

List of NetworkConnection objects.

required
header str

Header text for the output.

'=== Active Network Connections ===\n'

Returns:

Type Description
str

Formatted string representation.

Source code in src/linux_mcp_server/formatters.py
def format_network_connections(
    connections: list[NetworkConnection],
    header: str = "=== Active Network Connections ===\n",
) -> str:
    """Format network connections into a readable string.

    Args:
        connections: List of NetworkConnection objects.
        header: Header text for the output.

    Returns:
        Formatted string representation.
    """
    lines = [header]
    lines.append(f"{'Proto':<8} {'Local Address':<30} {'Remote Address':<30} {'Status':<15} {'PID/Program'}")
    lines.append("-" * 110)

    for conn in connections:
        local = f"{conn.local_address}:{conn.local_port}"
        remote = f"{conn.remote_address}:{conn.remote_port}" if conn.remote_address else "N/A"
        lines.append(f"{conn.protocol:<8} {local:<30} {remote:<30} {conn.state:<15} {conn.process}")

    lines.append(f"\n\nTotal connections: {len(connections)}")
    return "\n".join(lines)

format_network_interfaces

format_network_interfaces(
    interfaces: dict[str, NetworkInterface],
    stats: dict[str, NetworkInterface] | None = None,
) -> str

Format network interface information into a readable string.

Parameters:

Name Type Description Default
interfaces dict[str, NetworkInterface]

Dictionary of interface name to NetworkInterface objects.

required
stats dict[str, NetworkInterface] | None

Optional dictionary of interface statistics.

None

Returns:

Type Description
str

Formatted string representation.

Source code in src/linux_mcp_server/formatters.py
def format_network_interfaces(
    interfaces: dict[str, NetworkInterface],
    stats: dict[str, NetworkInterface] | None = None,
) -> str:
    """Format network interface information into a readable string.

    Args:
        interfaces: Dictionary of interface name to NetworkInterface objects.
        stats: Optional dictionary of interface statistics.

    Returns:
        Formatted string representation.
    """
    lines = ["=== Network Interfaces ===\n"]

    for name, iface in sorted(interfaces.items()):
        lines.append(f"\n{name}:")
        if iface.status:
            lines.append(f"  Status: {iface.status}")
        for addr in iface.addresses:
            lines.append(f"  Address: {addr}")

        # Add stats if available
        if stats and name in stats:
            stat = stats[name]
            lines.append(f"  RX: {format_bytes(stat.rx_bytes)} ({stat.rx_packets} packets)")
            lines.append(f"  TX: {format_bytes(stat.tx_bytes)} ({stat.tx_packets} packets)")
            if stat.rx_errors or stat.tx_errors:
                lines.append(f"  Errors: RX={stat.rx_errors}, TX={stat.tx_errors}")
            if stat.rx_dropped or stat.tx_dropped:
                lines.append(f"  Dropped: RX={stat.rx_dropped}, TX={stat.tx_dropped}")

    return "\n".join(lines)

format_process_detail

format_process_detail(
    ps_output: str,
    proc_status: dict[str, str] | None = None,
    pid: int | None = None,
) -> str

Format detailed process information.

Parameters:

Name Type Description Default
ps_output str

Raw output from ps command for the process.

required
proc_status dict[str, str] | None

Parsed /proc/{pid}/status content.

None
pid int | None

Process ID for the header.

None

Returns:

Type Description
str

Formatted string representation.

Source code in src/linux_mcp_server/formatters.py
def format_process_detail(
    ps_output: str,
    proc_status: dict[str, str] | None = None,
    pid: int | None = None,
) -> str:
    """Format detailed process information.

    Args:
        ps_output: Raw output from ps command for the process.
        proc_status: Parsed /proc/{pid}/status content.
        pid: Process ID for the header.

    Returns:
        Formatted string representation.
    """
    lines = []

    if pid:
        lines.append(f"=== Process Information for PID {pid} ===\n")

    lines.append(ps_output.strip())

    if proc_status:
        lines.append("\n=== Detailed Status (/proc) ===")
        for key, value in proc_status.items():
            lines.append(f"{key}: {value}")

    return "\n".join(lines)

format_process_list

format_process_list(
    processes: list[ProcessInfo],
    max_display: int | None = None,
    header: str = "=== Running Processes ===\n",
) -> str

Format process list into a readable string.

Parameters:

Name Type Description Default
processes list[ProcessInfo]

List of ProcessInfo objects.

required
max_display int | None

Maximum number of processes to display.

None
header str

Header text for the output.

'=== Running Processes ===\n'

Returns:

Type Description
str

Formatted string representation.

Source code in src/linux_mcp_server/formatters.py
def format_process_list(
    processes: list[ProcessInfo],
    max_display: int | None = None,
    header: str = "=== Running Processes ===\n",
) -> str:
    """Format process list into a readable string.

    Args:
        processes: List of ProcessInfo objects.
        max_display: Maximum number of processes to display.
        header: Header text for the output.

    Returns:
        Formatted string representation.
    """
    lines = [header]
    lines.append(f"{'PID':<8} {'User':<12} {'CPU%':<8} {'Memory%':<10} {'Status':<12} {'Name':<30} {'Command'}")
    lines.append("-" * 120)

    displayed = processes[:max_display] if max_display is not None else processes
    for proc in displayed:
        # Truncate username if too long
        username = proc.user
        if len(username) > 12:
            username = username[:9] + "..."

        # Truncate command if too long
        cmd = proc.command
        if len(cmd) > 40:
            cmd = cmd[:37] + "..."

        lines.append(
            f"{proc.pid:<8} {username:<12} {proc.cpu_percent:<8} {proc.mem_percent:<10} "
            f"{proc.stat:<12} {proc.command[:30]:<30} {cmd}"
        )

    lines.append(f"\n\nTotal processes: {len(processes)}")
    if max_display is not None and len(processes) > max_display:
        lines.append(f"Showing: First {max_display} processes")

    return "\n".join(lines)

format_service_logs

format_service_logs(
    stdout: str, service_name: str, lines_count: int
) -> str

Format service logs output.

Parameters:

Name Type Description Default
stdout str

Raw output from journalctl.

required
service_name str

Name of the service.

required
lines_count int

Number of log lines requested.

required

Returns:

Type Description
str

Formatted string representation.

Source code in src/linux_mcp_server/formatters.py
def format_service_logs(stdout: str, service_name: str, lines_count: int) -> str:
    """Format service logs output.

    Args:
        stdout: Raw output from journalctl.
        service_name: Name of the service.
        lines_count: Number of log lines requested.

    Returns:
        Formatted string representation.
    """
    lines = [f"=== Last {lines_count} log entries for {service_name} ===\n"]
    lines.append(stdout)
    return "\n".join(lines)

format_service_status

format_service_status(
    stdout: str, service_name: str
) -> str

Format service status output.

Parameters:

Name Type Description Default
stdout str

Raw output from systemctl status.

required
service_name str

Name of the service.

required

Returns:

Type Description
str

Formatted string representation.

Source code in src/linux_mcp_server/formatters.py
def format_service_status(stdout: str, service_name: str) -> str:
    """Format service status output.

    Args:
        stdout: Raw output from systemctl status.
        service_name: Name of the service.

    Returns:
        Formatted string representation.
    """
    lines = [f"=== Status of {service_name} ===\n"]
    lines.append(stdout)
    return "\n".join(lines)

format_services_list

format_services_list(
    stdout: str, running_count: int | None = None
) -> str

Format service list output.

Parameters:

Name Type Description Default
stdout str

Raw output from systemctl list-units.

required
running_count int | None

Optional count of running services.

None

Returns:

Type Description
str

Formatted string representation.

Source code in src/linux_mcp_server/formatters.py
def format_services_list(stdout: str, running_count: int | None = None) -> str:
    """Format service list output.

    Args:
        stdout: Raw output from systemctl list-units.
        running_count: Optional count of running services.

    Returns:
        Formatted string representation.
    """
    lines = ["=== System Services ===\n"]
    lines.append(stdout)

    if running_count is not None:
        lines.append(f"\n\nSummary: {running_count} services currently running")

    return "\n".join(lines)

format_system_info

format_system_info(info: SystemInfo) -> str

Format system information into a readable string.

Parameters:

Name Type Description Default
info SystemInfo

SystemInfo object.

required

Returns:

Type Description
str

Formatted string representation.

Source code in src/linux_mcp_server/formatters.py
def format_system_info(info: SystemInfo) -> str:
    """Format system information into a readable string.

    Args:
        info: SystemInfo object.

    Returns:
        Formatted string representation.
    """
    lines = []

    if info.hostname:
        lines.append(f"Hostname: {info.hostname}")
    if info.os_name:
        lines.append(f"Operating System: {info.os_name}")
    if info.os_version:
        lines.append(f"OS Version: {info.os_version}")
    if info.kernel:
        lines.append(f"Kernel Version: {info.kernel}")
    if info.arch:
        lines.append(f"Architecture: {info.arch}")
    if info.uptime:
        lines.append(f"Uptime: {info.uptime}")
    if info.boot_time:
        lines.append(f"Boot Time: {info.boot_time}")

    return "\n".join(lines)