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)}`);
      }
    }
Behavior2/5

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

With no annotations provided, the description carries full burden for behavioral disclosure. While it mentions the workflow (find field, focus, then type), it doesn't address important behavioral aspects like: whether this simulates actual keyboard input or just sets text value, error conditions, performance characteristics, or what happens if the text field isn't found. The description provides some context but leaves significant behavioral questions unanswered.

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 perfectly concise and well-structured: one sentence defines the tool's purpose and scope, the next provides clear usage instructions. Every word earns its place with zero redundancy or wasted space. It's front-loaded with the core functionality followed by practical guidance.

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 complexity of a UI automation tool with 2 required parameters, 0% schema coverage, no annotations, and no output schema, the description is insufficiently complete. It provides basic usage workflow but lacks critical information about parameter meanings, error handling, behavioral details, and expected outcomes. For a tool that interacts with simulators and UI elements, more context is needed for reliable agent usage.

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

Parameters2/5

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

Schema description coverage is 0%, so the schema provides no parameter documentation. The description mentions 'text' parameter implicitly but doesn't explain either parameter's purpose or constraints. It doesn't clarify what 'simulatorUuid' is or why it's required, nor does it provide guidance on the 'text' parameter beyond the vague 'supports US keyboard characters' statement. The description adds minimal value beyond what's in the bare schema.

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 action ('Type text') and specifies the scope ('supports US keyboard characters'), which is a specific verb+resource combination. However, it doesn't explicitly distinguish this tool from sibling tools like 'key_press' or 'key_sequence' that might also involve keyboard input, leaving some ambiguity about when to choose this specific typing method.

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

Usage Guidelines4/5

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

The description provides clear context about when to use this tool: 'Use describe_ui to find text field, tap to focus, then type.' This gives a practical workflow sequence. However, it doesn't explicitly state when NOT to use it or mention alternatives among the many sibling tools, so it's not a complete usage guide.

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

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