npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

linux-system-mcp

v1.0.7

Published

MCP server for Linux desktop notifications, interactive dialogs, and shell access

Readme

🐧 Linux System MCP Server

The ultimate bridge between AI Agents and the Linux Desktop.

Vibe CodedBuilt with the mind and idea of a human, and the execution and speed of an AI.

Welcome, Linux lovers! We are open-sourcing this Model Context Protocol (MCP) server because the Linux desktop deserves first-class AI integration. This project provides a critical safety and usability layer, allowing AI agents to interact with your system intelligently, safely, and interactively.

Provides desktop notifications, interactive GUI dialogs, shell command execution, privileged command execution (sudo/su), file editing, and file/URL launching.

🌟 Why This Project?

Fills a real gap - Most MCP servers focus on APIs, databases, and cloud services. Desktop GUI integration for Linux is severely underserved. This bridges the gap between AI agents and the Linux desktop.

Safety layer for AI agents - The ability for an AI agent to ask for confirmation via GUI before running destructive commands (rm -rf, dd, etc.) is a very meaningful safety feature that doesn't exist in terminal-only workflows.

Better UX - Fire-and-forget notifications for long-running tasks (builds, deployments) without polluting the terminal output. The agent can inform you immediately when tasks complete.

Universal approach - Desktop environment detection with a fallback chain (kdialogzenitynotify-send) makes it work seamlessly across KDE, GNOME, XFCE, and others. Most similar attempts are DE-specific.

Enables human-in-the-loop workflows - Bridges asynchronous AI agents with synchronous human decisions. The agent can now "wait" for real user input mid-execution, enabling complex workflows like:

  • Run a command → analyze the output → ask the user → proceed or abort
  • Propose multiple solutions → let the user choose → implement the selected option

Token-efficient tool discovery - Uses a linux_system_tool_search meta-tool so only one tool schema is loaded into the LLM context at startup. The LLM searches for tools by keyword, dramatically reducing your token usage at connection time!


⚡ Features

  • Desktop Notifications - Fire-and-forget notifications via notify-send/kdialog/zenity
  • Interactive Dialogs - A unified ask_user tool for Yes/No confirmations, single-choice, multi-select, text input, alerts, and password prompts
  • Shell Execution - Run non-interactive shell commands with timeout and output capture
  • Sudo with GUI Password - Execute privileged commands with GUI password prompts (pkexec/askpass/su)
  • XDG Open - Open files, directories, or URLs in the user's default desktop application
  • Backend Stats - Inspect which dialog/notify backends are available and their system health
  • Tool Search - Meta-tool for efficient token-saving tool discovery
  • MCP Prompts - Reusable prompt templates for common agent workflows
  • Universal DE Support - Auto-detects KDE (kdialog) or GTK environments (zenity) with graceful fallbacks

🚀 Requirements

  • Node.js 18+
  • Any Linux desktop environment
  • One of the following GUI tools:
    • notify-send (minimal feature set - notifications only)
    • kdialog (KDE - full support)
    • zenity (GTK/GNOME/XFCE - full support)

Install dialog tools (Arch Linux / Manjaro)

# For KDE users
sudo pacman -S kdialog

# For GNOME/XFCE/Other GTK users
sudo pacman -S zenity

🚀 Quick Start (No Installation Required)

You can run this MCP server instantly using npx—no need to clone or build!

Usage with Claude Desktop / Claude Code

Add this directly to your claude_desktop_config.json or ~/.claude/settings.json:

{
  "mcpServers": {
    "linux-system": {
      "command": "npx",
      "args": ["-y", "linux-system-mcp"]
    }
  }
}

Note: If the package isn't published to npm yet, use github:dgpl-mcps/linux_system_mcp instead of linux-system-mcp.

Manual Installation (Development)

If you prefer to clone and run it locally:

git clone https://github.com/dgpl-mcps/linux_system_mcp.git
cd linux_system_mcp
npm install
npm run build

Then in your MCP client configuration, point to the local file:

{
  "mcpServers": {
    "linux-system": {
      "command": "node",
      "args": ["/absolute/path/to/linux_system_mcp/dist/index.js"]
    }
  }
}

🧠 Token-Saving Defer Loading (default: enabled)

By default, only linux_system_tool_search is exposed to the LLM at connection time. The LLM must call linux_system_tool_search first to discover what tools are available before calling them. This drastically reduces token usage at startup since only one schema is loaded instead of all tool schemas.

To disable (show all tools upfront — useful for debugging):

{
  "mcpServers": {
    "linux-system": {
      "command": "npx",
      "args": ["-y", "linux-system-mcp"],
      "env": {
        "defer_loading": "false"
      }
    }
  }
}

🛠️ Available Tools

linux_system_tool_search (meta)

Search for available tools by keyword. Always call this first when you need a specific capability and aren't sure which tool to use.

{ "query": "notification" }

Returns names, descriptions, and full schemas for all matching tools.


notify

Send a fire-and-forget desktop notification. Appears in the system tray/notification area. Does not wait for user acknowledgement.

{
  "title": "Build Complete",
  "message": "Your project has been built successfully",
  "urgency": "normal",
  "timeout": 5
}

Parameters:

  • urgency: "low" | "normal" | "critical" (default: "normal")
  • timeout: seconds to show the notification (default: 5)

Returns: { "success": true, "backend": "kdialog", "method": "kdialog" }


ask_user

Show an interactive GUI dialog to the user and return their response. This unified tool handles all user interactions via the op (operation) parameter.

{
  "op": "confirmation",
  "title": "Confirm Delete",
  "message": "Are you sure you want to delete these files?"
}

Operations (op):

  • "confirmation": Shows a Yes/No dialog. Blocks until user responds.
    • Returns: { "confirmed": true/false, "backend": "kdialog" }
  • "choice": Single-selection list. choices parameter is required.
    • Returns: { "selected": "npm", "index": 0, "cancelled": false, "backend": "kdialog" }
  • "multi_check": Multi-select (checkbox) dialog. choices parameter is required.
    • Returns: { "selected": ["TypeScript", "Tests"], "indices": [0, 3], "cancelled": false, "backend": "kdialog" }
  • "input": Text input dialog. Supports optional default_value.
    • Returns: { "input": "myfile.txt", "cancelled": false, "backend": "kdialog" }
  • "alert": OK-only alert dialog. Blocks until user dismisses it.
    • Returns: { "acknowledged": true, "backend": "kdialog" }
  • "password": Masked password input dialog.
    • Returns: { "password": "...", "cancelled": false, "backend": "kdialog" }

Advanced — Tool Chaining: Use ask_user sequentially to create workflows. For example, ask a multiple choice question (op: "choice"), and if they select "Custom", follow up with a text input prompt (op: "input").


shell_execute

Execute a shell command and return stdout, stderr, and exit code. Non-interactive only. Supports pipes, redirects, and multi-command chains (&&, ;).

{
  "command": "df -h",
  "working_dir": "/home/user",
  "timeout": 30
}

Parameters:

  • working_dir: defaults to user home directory
  • timeout: seconds (default: 30)
  • shell: shell binary (default: /bin/bash)

Returns: { "stdout": "...", "stderr": "", "exit_code": 0, "timed_out": false, "working_dir": "/home/user" }


sudo_execute

Execute a command with elevated privileges or as a specific user. Shows a GUI password dialog before running.

Run as root with PolicyKit:

{
  "command": "pacman -Syu --noconfirm",
  "method": "pkexec",
  "timeout": 600
}

Run as specific user (AUR helpers like paru/yay refuse to run as root):

{
  "command": "paru -S google-chrome --noconfirm",
  "method": "su",
  "run_as_user": "myuser",
  "timeout": 600
}

Auto-detect best method:

{
  "command": "systemctl restart nginx",
  "timeout": 30
}

Parameters:

  • method: Authentication method (default: "auto"):
    • auto — Smart auto-detection: picks su if run_as_user is set, askpass if current user is in sudoers, otherwise pkexec
    • askpass — sudo with GUI askpass prompt; requires current user to be in sudoers
    • pkexec — PolicyKit; shows system-level auth dialog; works for any user
    • su — Authenticates as the target user (not root); asks for their password
  • run_as_user: Run the command as this user instead of root (essential for AUR helpers)
  • login_shell: Use login shell (-i) to load the user's full environment (.bashrc, .profile). askpass method only.
  • preserve_env: Preserve current environment variables (-E). askpass method only, cannot combine with login_shell.
  • nested_askpass: Enable GUI password prompt for nested sudo calls inside the command. Auto-enabled for paru/yay/pikaur.
  • notify_on_error: Send a desktop notification when the command fails with error details and a fix suggestion (default: true)
  • working_dir: Working directory (default: user home, or target user's home for su method)
  • timeout: Seconds (default: 120)

Returns:

{
  "stdout": "...",
  "stderr": "",
  "exit_code": 0,
  "timed_out": false,
  "cancelled": false,
  "method_used": "pkexec",
  "run_as": "root"
}

On failure, also returns error_summary:

{
  "error_summary": {
    "type": "auth_failed",
    "message": "Authentication failure",
    "context": ["su: Authentication failure"],
    "suggestion": "Wrong password entered. Try again with correct password."
  }
}

Error types: auth_failed, not_in_sudoers, command_not_found, permission_denied, timeout, cancelled, unknown

Context notifications: Before showing the password dialog, a desktop notification appears showing what command is about to run.


xdg_open

Open a file, directory, or URL using the user's default desktop application. Fire-and-forget (does not wait for the app to close).

{ "target": "/home/user/Downloads/report.pdf" }
{ "target": "https://docs.example.com" }

Returns: { "success": true, "message": "Opened ... in the default desktop application." }


get_dialog_backend_stats (meta)

Inspect which dialog and notification backends are available, and their success/failure statistics. Useful for debugging when dialogs aren't appearing.

{}

Returns:

{
  "availableDialogBackends": [
    { "name": "kdialog", "available": true },
    { "name": "zenity", "available": false }
  ],
  "availableNotifyBackends": ["kdialog", "notify-send"],
  "stats": {
    "dialog": { "kdialog": { "success": 5, "failures": 0, "consecutiveFailures": 0 } },
    "notify": { "kdialog": { "success": 3, "failures": 0, "consecutiveFailures": 0 } }
  }
}

🎬 MCP Prompts

The server exposes two reusable prompt templates:

interactive_script_creation

A prompt that guides an agent to: ask the user what the script should do, generate it with file_edit, and offer to run it via shell_execute.

open_workspace

A prompt that asks the user for a directory path and opens it via xdg_open.


🦾 Suggested Workflows for AI Agents

1. System Monitoring with Alerts

User: "Check my disk usage and warn me if any partition is over 80%"

Agent Flow:
1. shell_execute({ command: "df -h" })
2. Parse output, find partitions over threshold
3. notify({
     title: "Disk Space Warning",
     message: "/save_data is at 81% (58G free)",
     urgency: "critical"
   })

2. Safe Destructive Operations

User: "Delete all .log files older than 7 days"

Agent Flow:
1. shell_execute({ command: "find /var/log -name '*.log' -mtime +7" })
2. ask_user({
     op: "confirmation",
     title: "Confirm Deletion",
     message: "Found 23 .log files older than 7 days. Delete them?"
   })
3. If confirmed → shell_execute({ command: "find ... -delete" })
4. notify({ title: "Cleanup Complete", message: "Deleted 23 log files" })

3. Interactive Package Management

User: "Install a code editor"

Agent Flow:
1. ask_user({
     op: "choice",
     title: "Select Editor",
     message: "Which editor do you want to install?",
     choices: ["VS Code", "Neovim", "Sublime Text", "Emacs"]
   })
2. If selected "VS Code" → shell_execute({ command: "yay -S visual-studio-code-bin" })
3. notify({ title: "Installation Complete", message: "VS Code installed successfully" })

4. Configuration with User Input

User: "Set up a new Git repository"

Agent Flow:
1. ask_user({
     op: "input",
     title: "Repository Name",
     message: "Enter the project name:",
     default_value: "my-project"
   })
2. shell_execute({ command: "mkdir <input> && cd <input> && git init" })
3. ask_user({
     op: "choice",
     title: "Add .gitignore?",
     message: "Select project type for .gitignore:",
     choices: ["Node.js", "Python", "Rust", "None"]
   })
4. notify({ title: "Repository Created", message: "<input> initialized with Git" })

5. Safe Config File Editing

User: "Change my shell prompt color"

Agent Flow:
1. shell_execute({ command: "cat ~/.bashrc | grep PS1" })
2. ask_user({
     op: "choice",
     title: "Select Color",
     message: "Choose prompt color:",
     choices: ["Green", "Blue", "Red", "Yellow"]
   })
3. (Edit ~/.bashrc manually or enable file_edit tool)
4. notify({ title: "Config Updated", message: "Restart terminal to see changes" })

6. Build & Deploy with Notifications

User: "Build my project and let me know when done"

Agent Flow:
1. notify({ title: "Build Started", message: "Running npm build...", urgency: "low" })
2. shell_execute({ command: "npm run build", timeout: 300 })
3. If exit_code == 0:
     notify({ title: "Build Successful", message: "Ready to deploy!", urgency: "normal" })
   Else:
     notify({ title: "Build Failed", message: "Check terminal for errors", urgency: "critical" })
     ask_user({ op: "confirmation", title: "View Logs?", message: "Open build log in editor?" })

7. Multi-Step System Administration (with sudo)

User: "Update my system"

Agent Flow:
1. ask_user({
     op: "confirmation",
     title: "System Update",
     message: "This will update all packages. Continue?"
   })
2. If confirmed:
     notify({ title: "Update Started", message: "Syncing repositories..." })
     sudo_execute({ command: "pacman -Syu --noconfirm", method: "pkexec", timeout: 600 })
     // User sees GUI password dialog from PolicyKit
3. If exit_code == 0:
     notify({ title: "Update Complete", message: "System is up to date" })
     ask_user({ op: "confirmation", title: "Reboot?", message: "Some updates may require a reboot." })

8. Service Management

User: "Restart nginx"

Agent Flow:
1. sudo_execute({ command: "systemctl status nginx" })
2. ask_user({
     op: "confirmation",
     title: "Restart Service",
     message: "nginx is running. Restart it?"
   })
3. If confirmed:
     sudo_execute({ command: "systemctl restart nginx", method: "askpass" })
     // User sees kdialog password prompt
4. notify({ title: "Service Restarted", message: "nginx is now running" })

9. AUR Package Installation (paru/yay)

User: "Install google-chrome from AUR"

Agent Flow:
1. ask_user({
     op: "confirmation",
     title: "AUR Installation",
     message: "Install google-chrome from AUR? This will build from source."
   })
2. If confirmed:
     notify({ title: "AUR Install", message: "Starting paru...", urgency: "low" })
     sudo_execute({
       command: "paru -S google-chrome --noconfirm",
       method: "su",
       run_as_user: "myuser",  // AUR helpers refuse to run as root
       login_shell: true,
       timeout: 600
     })
3. If exit_code == 0:
     notify({ title: "Installation Complete", message: "google-chrome installed" })
   Else:
     notify({ title: "Installation Failed", message: "Check build logs", urgency: "critical" })

10. Multi-Select Configuration

User: "Set up my new development environment"

Agent Flow:
1. ask_user({
     op: "multi_check",
     title: "Dev Environment Setup",
     message: "Select tools to install:",
     choices: ["Node.js", "Python", "Docker", "Git", "VS Code"]
   })
2. For each selected tool → sudo_execute({ command: "pacman -S <tool>" })
3. notify({ title: "Setup Complete", message: "Installed: Node.js, Docker, Git" })

11. Debugging Dialog Backends

User: "Why aren't dialogs showing up?"

Agent Flow:
1. get_dialog_backend_stats({})
2. Check availableDialogBackends for which backends are found
3. If none available → notify user that kdialog or zenity must be installed
4. ask_user({
     op: "alert",
     title: "Backend Status",
     message: "kdialog: available, zenity: not found"
   })

📋 Cheat Sheet: Key Patterns for Agents

| Pattern | When to Use | Tools | |---------|-------------|-------| | Search First | Don't know which tool to use | linux_system_tool_search | | Query → Notify | System info, monitoring | shell_executenotify | | Confirm → Execute | Destructive operations | ask_user (op="confirmation") → shell_execute | | Choose → Execute | Multiple options available | ask_user (op="choice") → shell_execute | | Multi-Select → Execute | Multiple selections needed | ask_user (op="multi_check") → shell_execute | | Input → Configure | Custom values needed | ask_user (op="input") → shell_execute | | Execute → Notify | Long-running tasks | shell_executenotify | | Sudo with GUI | Privileged operations | sudo_execute (askpass or pkexec) | | Run as User | AUR helpers (paru/yay) | sudo_execute with run_as_user | | Open Result | Show user a file/URL | xdg_open | | Force Acknowledge | Critical blocking alerts | ask_user (op="alert") | | Collect Secret | SSH/API passwords | ask_user (op="password") | | Debug Backends | Dialogs not appearing | get_dialog_backend_stats |

🏢 Credits

Powered and maintained by DGPL (Durbhasi Gurukulam Private Limited) — an IT, Cybersecurity, and Edutech company.

📜 License

MIT License. Open-sourced for the community to make Linux the best workstation for AI Agents.