Skip to main content
Glama

key_press

Simulate key presses on an iOS simulator using keycodes, enabling testing of keyboard interactions in app development. Supports common keys like Return, Backspace, Tab, and Space.

Instructions

Press a single key by keycode on the simulator. Common keycodes: 40=Return, 42=Backspace, 43=Tab, 44=Space, 58-67=F1-F10.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
durationNo
keyCodeYes
simulatorUuidYes

Implementation Reference

  • Core handler function implementing the key_press tool logic. Parses params, constructs axe 'key' command, executes it via executor, handles errors and returns responses.
    export async function key_pressLogic(
      params: KeyPressParams,
      executor: CommandExecutor,
      axeHelpers: AxeHelpers = {
        getAxePath,
        getBundledAxeEnvironment,
        createAxeNotAvailableResponse,
      },
    ): Promise<ToolResponse> {
      const toolName = 'key_press';
      const { simulatorId, keyCode, duration } = params;
      const commandArgs = ['key', String(keyCode)];
      if (duration !== undefined) {
        commandArgs.push('--duration', String(duration));
      }
    
      log('info', `${LOG_PREFIX}/${toolName}: Starting key press ${keyCode} on ${simulatorId}`);
    
      try {
        await executeAxeCommand(commandArgs, simulatorId, 'key', executor, axeHelpers);
        log('info', `${LOG_PREFIX}/${toolName}: Success for ${simulatorId}`);
        return createTextResponse(`Key press (code: ${keyCode}) simulated successfully.`);
      } catch (error) {
        log('error', `${LOG_PREFIX}/${toolName}: Failed - ${error}`);
        if (error instanceof DependencyError) {
          return axeHelpers.createAxeNotAvailableResponse();
        } else if (error instanceof AxeError) {
          return createErrorResponse(
            `Failed to simulate key press (code: ${keyCode}): ${error.message}`,
            error.axeOutput,
          );
        } else if (error instanceof SystemError) {
          return createErrorResponse(
            `System error executing axe: ${error.message}`,
            error.originalError?.stack,
          );
        }
        return createErrorResponse(
          `An unexpected error occurred: ${error instanceof Error ? error.message : String(error)}`,
        );
      }
    }
  • Zod schema defining the input parameters for the key_press tool: simulatorId (UUID), keyCode (0-255), optional duration.
    const keyPressSchema = z.object({
      simulatorId: z.string().uuid('Invalid Simulator UUID format'),
      keyCode: z.number().int('HID keycode to press (0-255)').min(0).max(255),
      duration: z.number().min(0, 'Duration must be non-negative').optional(),
    });
  • Tool registration exporting the key_press tool with name, description, public schema (omitting simulatorId), and session-aware handler wrapping the logic function.
    const publicSchemaObject = keyPressSchema.omit({ simulatorId: true } as const).strict();
    
    export default {
      name: 'key_press',
      description:
        'Press a single key by keycode on the simulator. Common keycodes: 40=Return, 42=Backspace, 43=Tab, 44=Space, 58-67=F1-F10.',
      schema: publicSchemaObject.shape, // MCP SDK compatibility
      handler: createSessionAwareTool<KeyPressParams>({
        internalSchema: keyPressSchema as unknown as z.ZodType<KeyPressParams>,
        logicFunction: (params: KeyPressParams, executor: CommandExecutor) =>
          key_pressLogic(params, executor, {
            getAxePath,
            getBundledAxeEnvironment,
            createAxeNotAvailableResponse,
          }),
        getExecutor: getDefaultCommandExecutor,
        requirements: [{ allOf: ['simulatorId'], message: 'simulatorId is required' }],
      }),
    };
  • Inline helper function to execute axe commands, used by the key_press handler. Handles axe binary path, udid, environment, execution, and error wrapping.
    async function executeAxeCommand(
      commandArgs: string[],
      simulatorId: string,
      commandName: string,
      executor: CommandExecutor = getDefaultCommandExecutor(),
      axeHelpers: AxeHelpers = { getAxePath, getBundledAxeEnvironment, createAxeNotAvailableResponse },
    ): Promise<void> {
      // Get the appropriate axe binary path
      const axeBinary = axeHelpers.getAxePath();
      if (!axeBinary) {
        throw new DependencyError('AXe binary not found');
      }
    
      // Add --udid parameter to all commands
      const fullArgs = [...commandArgs, '--udid', simulatorId];
    
      // Construct the full command array with the axe binary as the first element
      const fullCommand = [axeBinary, ...fullArgs];
    
      try {
        // Determine environment variables for bundled AXe
        const axeEnv = axeBinary !== 'axe' ? axeHelpers.getBundledAxeEnvironment() : undefined;
    
        const result = await executor(fullCommand, `${LOG_PREFIX}: ${commandName}`, false, axeEnv);
    
        if (!result.success) {
          throw new AxeError(
            `axe command '${commandName}' failed.`,
            commandName,
            result.error ?? result.output,
            simulatorId,
          );
        }
    
        // Check for stderr output in successful commands
        if (result.error) {
          log(
            'warn',
            `${LOG_PREFIX}: Command '${commandName}' produced stderr output but exited successfully. Output: ${result.error}`,
          );
        }
    
        // Function now returns void - the calling code creates its own response
      } catch (error) {
        if (error instanceof Error) {
          if (error instanceof AxeError) {
            throw error;
          }
    
          // Otherwise wrap it in a SystemError
          throw new SystemError(`Failed to execute axe command: ${error.message}`, error);
        }
    
        // For any other type of error
        throw new SystemError(`Failed to execute axe command: ${String(error)}`);
      }
    }

Tool Definition Quality

Score is being calculated. Check back soon.

Install Server

Other Tools

Related 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/getsentry/XcodeBuildMCP'

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