Skip to main content
Glama

type_text

Input text into simulator fields using US keyboard characters. First, identify text fields with describe_ui, focus with tap, then type the desired text.

Instructions

Type text (supports US keyboard characters). Use describe_ui to find text field, tap to focus, then type.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
simulatorUuidYes
textYes

Implementation Reference

  • The core handler function that executes the type_text tool logic, destructuring parameters, preparing axe command args, executing via executeAxeCommand, logging, and returning success/error responses based on error types.
    export async function type_textLogic(
      params: TypeTextParams,
      executor: CommandExecutor,
      axeHelpers?: AxeHelpers,
    ): Promise<ToolResponse> {
      const toolName = 'type_text';
    
      // Params are already validated by the factory, use directly
      const { simulatorId, text } = params;
      const commandArgs = ['type', text];
    
      log(
        'info',
        `${LOG_PREFIX}/${toolName}: Starting type "${text.substring(0, 20)}..." on ${simulatorId}`,
      );
    
      try {
        await executeAxeCommand(commandArgs, simulatorId, 'type', executor, axeHelpers);
        log('info', `${LOG_PREFIX}/${toolName}: Success for ${simulatorId}`);
        return createTextResponse('Text typing simulated successfully.');
      } catch (error) {
        log(
          'error',
          `${LOG_PREFIX}/${toolName}: Failed - ${error instanceof Error ? error.message : String(error)}`,
        );
        if (error instanceof DependencyError) {
          return createAxeNotAvailableResponse();
        } else if (error instanceof AxeError) {
          return createErrorResponse(
            `Failed to simulate text typing: ${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 input parameters (simulatorId as UUID, text as non-empty string), inferred TypeScript type TypeTextParams, and public schema omitting simulatorId.
    const typeTextSchema = z.object({
      simulatorId: z.string().uuid('Invalid Simulator UUID format'),
      text: z.string().min(1, 'Text cannot be empty'),
    });
    
    // Use z.infer for type safety
    type TypeTextParams = z.infer<typeof typeTextSchema>;
    
    const publicSchemaObject = typeTextSchema.omit({ simulatorId: true } as const).strict();
  • Default export registering the tool with name, description, public schema, and session-aware handler wrapping the type_textLogic function.
    export default {
      name: 'type_text',
      description:
        'Type text (supports US keyboard characters). Use describe_ui to find text field, tap to focus, then type.',
      schema: publicSchemaObject.shape, // MCP SDK compatibility
      handler: createSessionAwareTool<TypeTextParams>({
        internalSchema: typeTextSchema as unknown as z.ZodType<TypeTextParams>,
        logicFunction: (params: TypeTextParams, executor: CommandExecutor) =>
          type_textLogic(params, executor),
        getExecutor: getDefaultCommandExecutor,
        requirements: [{ allOf: ['simulatorId'], message: 'simulatorId is required' }],
      }), // Safe factory
    };
  • Internal helper function to execute axe binary commands on the specified simulator, handling binary path, UDID, environment, execution, error throwing with custom error types, and logging.
    async function executeAxeCommand(
      commandArgs: string[],
      simulatorId: string,
      commandName: string,
      executor: CommandExecutor = getDefaultCommandExecutor(),
      axeHelpers?: AxeHelpers,
    ): Promise<void> {
      // Use provided helpers or defaults
      const helpers = axeHelpers ?? { getAxePath, getBundledAxeEnvironment };
    
      // Get the appropriate axe binary path
      const axeBinary = helpers.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' ? helpers.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)}`);
      }
    }
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/cameroncooke/XcodeBuildMCP'

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