Skip to main content
Glama
nickgnd

Tmux MCP Server

by nickgnd

get-command-result

Retrieve output from a previously executed command in a tmux session to access terminal results for AI-assisted analysis and control.

Instructions

Get the result of an executed command

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
commandIdYesID of the executed command

Implementation Reference

  • The handler function that implements the core logic of the 'get-command-result' tool. It fetches the command status using tmux.checkCommandStatus, handles pending/completed/error states, and returns formatted text content.
    async ({ commandId }) => {
      try {
        // Check and update command status
        const command = await tmux.checkCommandStatus(commandId);
    
        if (!command) {
          return {
            content: [{
              type: "text",
              text: `Command not found: ${commandId}`
            }],
            isError: true
          };
        }
    
        // Format the response based on command status
        let resultText;
        if (command.status === 'pending') {
          if (command.result) {
            resultText = `Status: ${command.status}\nCommand: ${command.command}\n\n--- Message ---\n${command.result}`;
          } else {
            resultText = `Command still executing...\nStarted: ${command.startTime.toISOString()}\nCommand: ${command.command}`;
          }
        } else {
          resultText = `Status: ${command.status}\nExit code: ${command.exitCode}\nCommand: ${command.command}\n\n--- Output ---\n${command.result}`;
        }
    
        return {
          content: [{
            type: "text",
            text: resultText
          }]
        };
      } catch (error) {
        return {
          content: [{
            type: "text",
            text: `Error retrieving command result: ${error}`
          }],
          isError: true
        };
      }
    }
  • src/index.ts:394-443 (registration)
    Registration of the 'get-command-result' MCP tool using server.tool, including name, description, input schema, and handler reference.
    server.tool(
      "get-command-result",
      "Get the result of an executed command",
      {
        commandId: z.string().describe("ID of the executed command")
      },
      async ({ commandId }) => {
        try {
          // Check and update command status
          const command = await tmux.checkCommandStatus(commandId);
    
          if (!command) {
            return {
              content: [{
                type: "text",
                text: `Command not found: ${commandId}`
              }],
              isError: true
            };
          }
    
          // Format the response based on command status
          let resultText;
          if (command.status === 'pending') {
            if (command.result) {
              resultText = `Status: ${command.status}\nCommand: ${command.command}\n\n--- Message ---\n${command.result}`;
            } else {
              resultText = `Command still executing...\nStarted: ${command.startTime.toISOString()}\nCommand: ${command.command}`;
            }
          } else {
            resultText = `Status: ${command.status}\nExit code: ${command.exitCode}\nCommand: ${command.command}\n\n--- Output ---\n${command.result}`;
          }
    
          return {
            content: [{
              type: "text",
              text: resultText
            }]
          };
        } catch (error) {
          return {
            content: [{
              type: "text",
              text: `Error retrieving command result: ${error}`
            }],
            isError: true
          };
        }
      }
    );
  • Zod input schema for the tool, defining the required 'commandId' parameter.
    {
      commandId: z.string().describe("ID of the executed command")
    },
  • Core helper function checkCommandStatus that polls the tmux pane content, parses start/end markers to extract output and exit code, updating the command execution status in the activeCommands map.
    export async function checkCommandStatus(commandId: string): Promise<CommandExecution | null> {
      const command = activeCommands.get(commandId);
      if (!command) return null;
    
      if (command.status !== 'pending') return command;
    
      const content = await capturePaneContent(command.paneId, 1000);
    
      if (command.rawMode) {
        command.result = 'Status tracking unavailable for rawMode commands. Use capture-pane to monitor interactive apps instead.';
        return command;
      }
    
      // Find the last occurrence of the markers
      const startIndex = content.lastIndexOf(startMarkerText);
      const endIndex = content.lastIndexOf(endMarkerPrefix);
    
      if (startIndex === -1 || endIndex === -1 || endIndex <= startIndex) {
        command.result = "Command output could not be captured properly";
        return command;
      }
    
      // Extract exit code from the end marker line
      const endLine = content.substring(endIndex).split('\n')[0];
      const endMarkerRegex = new RegExp(`${endMarkerPrefix}(\\d+)`);
      const exitCodeMatch = endLine.match(endMarkerRegex);
    
      if (exitCodeMatch) {
        const exitCode = parseInt(exitCodeMatch[1], 10);
    
        command.status = exitCode === 0 ? 'completed' : 'error';
        command.exitCode = exitCode;
    
        // Extract output between the start and end markers
        const outputStart = startIndex + startMarkerText.length;
        const outputContent = content.substring(outputStart, endIndex).trim();
    
        command.result = outputContent.substring(outputContent.indexOf('\n') + 1).trim();
    
        // Update in map
        activeCommands.set(commandId, command);
      }
    
      return command;
    }

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/nickgnd/tmux-mcp'

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