# Tools Directory

This directory contains all MCP tools available in MCP Appium.

## Tool Categories

### Session Management (`session/`)

- `session.ts` - Unified session tool (`appium_session_management`; `action=create|delete|list|select`)
  - `create-session.ts` - Capability builders and `createSessionAction` (used by `session.ts`)
  - `delete-session.ts` - `deleteSessionAction` (used by `session.ts`)
  - `list-sessions.ts` - `listSessionsAction` (used by `session.ts`)
  - `select-session.ts` - `selectSessionAction` (used by `session.ts`)
- `select-device.ts` - Discover devices and select one (auto-selects if only one found)
- `device-control.ts` - Device controls in one tool (`appium_mobile_device_control`; `action=lock|unlock|shake|open_notifications`)
- `file-transfer.ts` - Push/pull files on device (`appium_mobile_file` with `action=push|pull`)
- `driver-settings.ts` - Read/update Appium driver session settings (`appium_driver_settings`, `action`: `get` \| `update`)

### iOS Setup (`ios/`)

- `prepare-ios-simulator.ts` - Boot simulator, download, install and launch WebDriverAgent in a single call
- `prepare-ios-real-device.ts` - Download the matching WDA release and resign it with a local provisioning profile. Discovery mode (no UUID) lists available `.mobileprovision` profiles (including wildcard ones, flagged as `recommendedForWda`); build mode (UUID) runs the signing pipeline. WDA download and unsigned IPA are cached per WDA version; the signed IPA is rebuilt every call so profile/cert rotation never serves a stale signature. Returns `usePreinstalledWDA` + `prebuiltWDAPath` capabilities so Appium installs and launches WDA during session startup.

### Navigation (`navigations/`)

- `scroll.ts` - Scroll screens
- `scroll-to-element.ts` - Scroll until element found
- `swipe.ts` - Swipe screens in any direction or between custom coordinates

### Element Interactions (`interactions/`)

- `find.ts` - Find elements
- `click.ts` - Click elements
- `double-tap.ts` - Double tap elements
- `long-press.ts` - Long press (press and hold) elements
- `drag-and-drop.ts` - Drag and drop elements or coordinates
- `press-key.ts` - Press navigation keys or physical buttons
- `set-value.ts` - Enter text
- `keyboard.ts` - Soft keyboard (`appium_mobile_keyboard`; `action=hide` \| `is_shown`)
- `get-text.ts` - Get element text
- `get-page-source.ts` - Get page source (XML) from current screen
- `screenshot.ts` - Capture screenshots

#### Element Search Priority Order

When searching for elements, follow this priority order for efficiency:

1. **`appium_get_active_element`** (PRIORITY 1) - Use this first to get the currently focused element
   - Lightweight and instant
   - Returns single element UUID
   - Best for: Finding what element currently has focus

2. **`appium_find_element`** (PRIORITY 2) - Use this to search for a specific target element
   - Specify strategy and selector
   - Strategy priority: `accessibility id` > `id` > platform-native (`-ios predicate string` / `-ios class chain` on iOS, `-android uiautomator` on Android) > `xpath` (last resort)
   - Returns specific element UUID
   - Best for: Targeting a known element

3. **`generate_locators`** (PRIORITY 3) - Use this for debugging/inspection only
   - Parses entire page source
   - Returns locators for all interactable elements
   - Best for: Understanding page structure, debugging, generating test code

### App Management (`app-management/`)

- `activate-app.ts` - Activate apps
- `background-app.ts` - Background the current app (`appium_mobile_background_app`)
- `deep-link.ts` - Open a deep link URL with the default or specified app
- `terminate-app.ts` - Terminate apps
- `install-app.ts` - Install apps
- `uninstall-app.ts` - Uninstall apps
- `clear-app.ts` - Clear app data / cache without uninstall (`appium_mobile_clear_app`; iOS Simulator only, Android broadly)
- `permissions.ts` - Unified mobile permissions (`appium_mobile_permissions`; action get / update / reset, platform-specific fields)
- `list-apps.ts` - List installed apps

### Context Management (`context/`)

- `context.ts` - Unified context operations (`appium_context`; `action=list|switch`)

### Test Generation (`test-generation/`)

- `locators.ts` - Generate page locators
- `generate-tests.ts` - Generate test code from scenarios

### Documentation (`documentation/`)

- `answer-appium.ts` - Answer Appium questions using RAG
- `appium-skills.ts` - Return ordered Appium environment setup or troubleshooting skills from the vendored appium/skills repository

## Adding a New Tool

See [docs/CONTRIBUTING.md](../../docs/CONTRIBUTING.md) for detailed instructions.

Quick steps:

1. Create a new file in the appropriate subdirectory (e.g., `interactions/my-tool.ts`)
2. Define the tool following the template
3. Import and register it in `index.ts`
4. Test with `npm run build && npm start`

### Tool Template

```typescript
import { FastMCP } from 'fastmcp/dist/FastMCP.js';
import { z } from 'zod';
import { getDriver } from '../../session-store.js';

export default function myTool(server: FastMCP): void {
  server.addTool({
    name: 'appium_my_tool',
    description: 'What this tool does',
    parameters: z.object({
      param: z.string().describe('Parameter description'),
    }),
    annotations: {
      readOnlyHint: false,
      openWorldHint: false,
    },
    execute: async (args: any, context: any): Promise<any> => {
      const driver = getDriver();
      if (!driver) {
        throw new Error('No active session');
      }

      // Implementation

      return {
        content: [
          {
            type: 'text',
            text: 'Success',
          },
        ],
      };
    },
  });
}
```

### Registering a Tool

Add to `src/tools/index.ts`:

```typescript
import myTool from './interactions/my-tool.js';

export default function registerTools(server: FastMCP): void {
  // ... existing tools ...
  myTool(server);
  // ...
}
```

## Best Practices

1. **Always check for active session**: Use `getDriver()` and check for null
2. **Provide helpful errors**: Give clear error messages
3. **Use proper types**: Leverage TypeScript and Zod for type safety
4. **Add logging**: Use the logger from `logger.js` for debugging. Import with: `import log from 'logger.js'`. Use `log.info()`, `log.error()`, `log.warn()` instead of `console.log/error/warn` to maintain JSON-RPC compatibility
5. **Handle errors**: Always wrap risky operations in try-catch
6. **Return proper format**: Always return content in expected MCP format

## Session Store

Tools interact with the session through `session-store.ts`:

```typescript
import {
  getDriver,
  hasActiveSession,
  safeDeleteSession,
} from '../../session-store.js';

// Check if session exists
if (!hasActiveSession()) {
  throw new Error('No active session');
}

// Get the driver
const driver = getDriver();

// Use the driver
await driver.someMethod();
```

## Common Patterns

### Platform-Specific Logic

```typescript
import { getPlatformName } from '../../session-store.js';

if (getPlatformName(driver) === 'Android') {
  // Android implementation
} else if (getPlatformName(driver) === 'iOS') {
  // iOS implementation
}
```

## Testing

After adding a new tool:

1. Build: `npm run build`
2. Run linter: `npm run lint`
3. Test with an MCP client
4. Verify tool appears in tools list

## Need Help?

- Check existing tools for examples
- Read [docs/CONTRIBUTING.md](../../docs/CONTRIBUTING.md)
- Look at examples in `examples/` directory
- Open an issue for questions
