Skip to main content
Glama
bvisible

MCP SSH Manager

ssh_command_alias

Create shortcuts for frequently used SSH commands to reduce typing and prevent errors. Manage aliases by adding, removing, listing, or getting suggestions for commands.

Instructions

Manage command aliases for frequently used commands

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionYesAction to perform
aliasNoAlias name (for add/remove)
commandNoCommand to alias (for add) or search term (for suggest)

Implementation Reference

  • Registration of 'ssh_command_alias' as part of the 'advanced' tool group in the central tool registry used for MCP tool management and conditional enabling.
    advanced: [
      'ssh_deploy',
      'ssh_execute_sudo',
      'ssh_alias',
      'ssh_command_alias',
      'ssh_hooks',
      'ssh_profile',
      'ssh_connection_status',
      'ssh_tunnel_create',
      'ssh_tunnel_list',
      'ssh_tunnel_close',
      'ssh_key_manage',
      'ssh_execute_group',
      'ssh_group_manage',
      'ssh_history'
    ]
  • Complete helper module providing all command alias management functionality (load/save/expand/add/remove/list/suggest) that implements the core logic for the ssh_command_alias tool.
    /**
     * Command Aliases System for MCP SSH Manager
     * Provides shortcuts for frequently used commands
     */
    
    import fs from 'fs';
    import path from 'path';
    import { fileURLToPath } from 'url';
    import { loadProfile } from './profile-loader.js';
    
    const __filename = fileURLToPath(import.meta.url);
    const __dirname = path.dirname(__filename);
    
    const ALIASES_FILE = path.join(__dirname, '..', '.command-aliases.json');
    
    // Get aliases from the active profile
    let profileAliases = {};
    try {
      const profile = loadProfile();
      profileAliases = profile.commandAliases || {};
    } catch (error) {
      console.error(`Error loading profile aliases: ${error.message}`);
    }
    
    /**
     * Load command aliases from file
     */
    export function loadCommandAliases() {
      try {
        // Start with profile aliases
        let aliases = { ...profileAliases };
    
        // Merge with custom aliases from file
        if (fs.existsSync(ALIASES_FILE)) {
          const data = fs.readFileSync(ALIASES_FILE, 'utf8');
          aliases = { ...aliases, ...JSON.parse(data) };
        }
    
        return aliases;
      } catch (error) {
        console.error(`Error loading command aliases: ${error.message}`);
      }
      return profileAliases;
    }
    
    /**
     * Save command aliases to file
     */
    export function saveCommandAliases(aliases) {
      try {
        // Only save custom aliases (not from profile)
        const customAliases = {};
        for (const [key, value] of Object.entries(aliases)) {
          if (profileAliases[key] !== value) {
            customAliases[key] = value;
          }
        }
    
        fs.writeFileSync(ALIASES_FILE, JSON.stringify(customAliases, null, 2));
        return true;
      } catch (error) {
        console.error(`Error saving command aliases: ${error.message}`);
        return false;
      }
    }
    
    /**
     * Expand command if it's an alias
     */
    export function expandCommandAlias(command) {
      const aliases = loadCommandAliases();
    
      // Check if the entire command is an alias
      if (aliases[command]) {
        return aliases[command];
      }
    
      // Check if the command starts with an alias
      const parts = command.split(' ');
      const firstPart = parts[0];
    
      if (aliases[firstPart]) {
        parts[0] = aliases[firstPart];
        return parts.join(' ');
      }
    
      return command;
    }
    
    /**
     * Add or update a command alias
     */
    export function addCommandAlias(alias, command) {
      const aliases = loadCommandAliases();
      aliases[alias] = command;
      return saveCommandAliases(aliases);
    }
    
    /**
     * Remove a command alias
     */
    export function removeCommandAlias(alias) {
      const aliases = loadCommandAliases();
    
      // Don't remove profile aliases, just reset them
      if (profileAliases[alias]) {
        aliases[alias] = profileAliases[alias];
      } else {
        delete aliases[alias];
      }
    
      return saveCommandAliases(aliases);
    }
    
    /**
     * List all command aliases
     */
    export function listCommandAliases() {
      const aliases = loadCommandAliases();
      const result = [];
    
      for (const [alias, command] of Object.entries(aliases)) {
        result.push({
          alias,
          command,
          isFromProfile: profileAliases[alias] === command,
          isCustom: profileAliases[alias] !== command
        });
      }
    
      return result.sort((a, b) => a.alias.localeCompare(b.alias));
    }
    
    /**
     * Get suggested aliases based on command
     */
    export function suggestAliases(command) {
      const suggestions = [];
      const aliases = loadCommandAliases();
    
      const commandLower = command.toLowerCase();
    
      for (const [alias, aliasCommand] of Object.entries(aliases)) {
        if (aliasCommand.toLowerCase().includes(commandLower) ||
            alias.toLowerCase().includes(commandLower)) {
          suggestions.push({ alias, command: aliasCommand });
        }
      }
    
      return suggestions;
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It states 'Manage command aliases' but lacks details on permissions required, whether changes are persistent, error handling, or output format. For a tool with multiple actions (add, remove, list, suggest), this is insufficient to inform the agent about operational behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence: 'Manage command aliases for frequently used commands.' It is front-loaded with the core purpose, has no redundant words, and appropriately sized for the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (multiple actions, no output schema, and no annotations), the description is incomplete. It doesn't explain what 'manage' entails operationally, the expected outcomes for each action, or how to interpret results. This leaves significant gaps for an agent to use the tool effectively.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with clear descriptions for all parameters (action, alias, command). The description adds no additional semantic information beyond the schema, such as examples or constraints. Since the schema handles parameter documentation well, the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Manage command aliases for frequently used commands.' It specifies the verb ('manage') and resource ('command aliases'), making the function understandable. However, it doesn't explicitly differentiate from sibling tools like 'ssh_alias' or 'ssh_profile', which might have overlapping functionality, preventing a perfect score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention any prerequisites, context-specific scenarios, or comparisons with sibling tools such as 'ssh_alias' or 'ssh_profile', leaving the agent without clear usage direction.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/bvisible/mcp-ssh-manager'

If you have feedback or need assistance with the MCP directory API, please join our Discord server