Skip to main content
Glama

inspect_app_state

Inspect mobile app preferences and databases to debug and analyze stored data on Android and iOS platforms.

Instructions

Inspect app preferences (SharedPreferences/UserDefaults) and SQLite databases. Can list all preferences, inspect specific databases, or run SQL queries.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
appIdYesApp package name (Android) or bundle ID (iOS)
platformYesTarget platform
deviceIdNoDevice ID (optional, uses first available)
includePreferencesNoInclude preferences in inspection (default: true)
includeDatabasesNoInclude databases in inspection (default: true)
preferencesFileNoSpecific preferences file to inspect
databaseNameNoSpecific database name to inspect or query
sqlQueryNoSQL query to execute (requires databaseName)
maxRowsNoMaximum rows to return from query (default: 100)
timeoutMsNoTimeout in milliseconds (default: 30000)

Implementation Reference

  • Core handler function that performs app state inspection: validates arguments, handles SQL queries or full state collection (preferences/databases), and returns structured results.
    export async function inspectAppState(args: InspectAppStateArgs): Promise<AppStateResult> { const { appId, platform, deviceId, includePreferences = true, includeDatabases = true, preferencesFile, databaseName, sqlQuery, maxRows = 100, timeoutMs = 30000, } = args; const startTime = Date.now(); // Validate platform if (!isPlatform(platform)) { throw Errors.invalidArguments(`Invalid platform: ${platform}. Must be 'android' or 'ios'`); } // Validate app ID if (!appId || appId.trim().length === 0) { throw Errors.invalidArguments('App ID is required'); } try { // If SQL query is provided, execute it directly if (sqlQuery && databaseName) { const queryResult = await executeSqlQuery( appId, platform, databaseName, sqlQuery, { deviceId, maxRows, timeoutMs } ); return { success: true, queryResult, durationMs: Date.now() - startTime, }; } // Collect app state const state = await collectAppState(appId, platform, { deviceId, includePreferences, includeDatabases, preferencesFile, databaseName, timeoutMs, }); return { success: true, state, durationMs: Date.now() - startTime, }; } catch (error) { return { success: false, error: String(error), durationMs: Date.now() - startTime, }; } }
  • TypeScript interface defining the input parameters for the inspect_app_state tool.
    export interface InspectAppStateArgs { /** App package/bundle ID */ appId: string; /** Target platform */ platform: string; /** Device ID */ deviceId?: string; /** Include preferences */ includePreferences?: boolean; /** Include databases */ includeDatabases?: boolean; /** Specific preferences file name */ preferencesFile?: string; /** Specific database name */ databaseName?: string; /** SQL query to run */ sqlQuery?: string; /** Maximum rows to return */ maxRows?: number; /** Timeout in milliseconds */ timeoutMs?: number; }
  • Registers the inspect_app_state tool with the MCP tool registry, including detailed input schema and a wrapper handler that calls the core inspectAppState function and adds formatted output.
    export function registerInspectAppStateTool(): void { getToolRegistry().register( 'inspect_app_state', { description: 'Inspect app preferences (SharedPreferences/UserDefaults) and SQLite databases. ' + 'Can list all preferences, inspect specific databases, or run SQL queries.', inputSchema: createInputSchema( { appId: { type: 'string', description: 'App package name (Android) or bundle ID (iOS)', }, platform: { type: 'string', enum: ['android', 'ios'], description: 'Target platform', }, deviceId: { type: 'string', description: 'Device ID (optional, uses first available)', }, includePreferences: { type: 'boolean', description: 'Include preferences in inspection (default: true)', }, includeDatabases: { type: 'boolean', description: 'Include databases in inspection (default: true)', }, preferencesFile: { type: 'string', description: 'Specific preferences file to inspect', }, databaseName: { type: 'string', description: 'Specific database name to inspect or query', }, sqlQuery: { type: 'string', description: 'SQL query to execute (requires databaseName)', }, maxRows: { type: 'number', description: 'Maximum rows to return from query (default: 100)', }, timeoutMs: { type: 'number', description: 'Timeout in milliseconds (default: 30000)', }, }, ['appId', 'platform'] ), }, async (args) => { const result = await inspectAppState(args as unknown as InspectAppStateArgs); return { ...result, formattedOutput: formatInspectionResult(result), }; } ); }
  • Helper function to format inspection results into readable markdown for AI consumption, handling both query results and full app state summaries.
    export function formatInspectionResult(result: AppStateResult): string { const lines: string[] = []; if (!result.success) { lines.push(`## App State Inspection: Failed`); lines.push(``); lines.push(`**Error**: ${result.error}`); return lines.join('\n'); } if (result.queryResult) { lines.push(`## SQL Query Result`); lines.push(``); lines.push(`**Rows**: ${result.queryResult.rowCount}`); lines.push(`**Columns**: ${result.queryResult.columns.join(', ')}`); lines.push(``); if (result.queryResult.rows.length > 0) { lines.push(`### Data`); lines.push(``); // Format as markdown table lines.push(`| ${result.queryResult.columns.join(' | ')} |`); lines.push(`| ${result.queryResult.columns.map(() => '---').join(' | ')} |`); for (const row of result.queryResult.rows.slice(0, 20)) { const values = result.queryResult.columns.map((col) => { const value = row[col]; if (value === null) return 'NULL'; if (typeof value === 'string' && value.length > 30) { return value.slice(0, 30) + '...'; } return String(value); }); lines.push(`| ${values.join(' | ')} |`); } if (result.queryResult.rows.length > 20) { lines.push(``); lines.push(`*Showing 20 of ${result.queryResult.rows.length} rows*`); } } return lines.join('\n'); } if (result.state) { return generateAppStateSummary(result.state); } return 'No data available'; }
  • Central tool registration during server startup: imports and invokes the tool's registration function.
    const { registerInspectAppStateTool } = await import('./observability/inspect-app-state.js'); const { registerInspectLogsTool } = await import('./observability/inspect-logs.js'); registerInspectAppStateTool(); registerInspectLogsTool();

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/abd3lraouf/specter-mcp'

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