AppInspect
Health Warn
- No license — Repository has no license file
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 6 GitHub stars
Code Fail
- fs.rmSync — Destructive file system operation in src/main/analysis/__tests__/debug-artifacts.test.ts
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Desktop app for analysing iOS and macOS binaries. View headers, strings, classes, symbols, security findings, and more.
AppInspect
A desktop app for analysing iOS and macOS binaries. Open an IPA, DEB, macOS .app bundle, or bare Mach-O/dylib and inspect its internals — headers, strings, classes, symbols, entitlements, security findings, and more.
Cross-platform for macOS, Windows, and Linux. Built with Electron and TypeScript. All analysis runs locally, offline, with no network requests.
Features
File format support
- IPA — extracts the app bundle, discovers the main executable plus embedded frameworks and app extensions
- macOS .app — supports macOS app bundles (
.app/Contents/MacOS/layout), discovers main executable, helper binaries, versioned frameworks, and plugins - DEB — extracts Debian packages (jailbreak tweaks), parses package metadata, discovers dylibs and bundle binaries
- Mach-O / dylib — analyses bare binaries directly (32-bit and 64-bit, fat/universal)
File type is detected automatically by magic bytes.
Analysis tabs
| Tab | Description |
|---|---|
| Overview | Mach-O header summary, binary hardening status (PIE, ARC, stack canaries, encryption, stripped), build version, UUID, team ID, detected frameworks |
| Strings | All embedded strings with section attribution and file offsets |
| Headers | Mach-O header fields, fat architecture list, full load command dump |
| Libraries | Linked frameworks and dylibs with version info and weak-linking flags. Interactive force-directed dependency graph view showing inter-binary relationships, with pan/zoom, node dragging, and category filtering |
| Symbols | Exported, imported, and local symbols with addresses. Swift symbols are demangled for display; the raw name stays searchable |
| Classes | ObjC class names and methods with decoded type signatures, protocol conformances per class, protocol detail view (required/optional instance/class methods), Logos hook generation, back/forward navigation history |
| Entitlements | Code signature entitlements or provisioning profile fallback |
| Localisation | Localisation strings from .lproj bundles with .strings file parsing |
| Info.plist | Key-facts summary at the top (bundle metadata, device family, supported platforms, privacy strings, ATS exceptions) above the full searchable key/value tree |
| Hooks | Jailbreak hook framework detection — Substrate, Libhooker, fishhook, Substitute, ObjC swizzling (Mach-O/DEB only) |
| Security | Credential leak scanning, weak crypto, unsafe APIs, dangerous syscalls, jailbreak detection strings, binary hardening assessment (issues only), leaked debug artifacts (DWARF, debug symbols, developer source paths, shipped source maps / Swift module interfaces / symbol maps), bundle file scanning (JS bundles, configs) |
| Hex | Raw hex viewer with virtual scrolling for large binaries. Segment/section region picker, go-to offset, hex/decimal offset toggle. Dual-mode search (hex bytes or text) with match highlighting and navigation |
| Files | Bundle file tree with sizes, context menu (copy path, open file, show in explorer/finder), double-click to open (IPA/DEB) |
Other capabilities
- Tabbed multi-file sessions — open multiple files simultaneously in separate tabs, each with independent analysis state (scroll position, filters, search, and tree expansions are per tab)
- Multi-binary switching — select between main app, frameworks, extensions, or multiple dylibs in a DEB
- Cross-binary search — search classes, strings, symbols, or libraries across all binaries in a container at once
- Fat binary architecture selector — choose which slice to analyse in universal binaries
- Jailbreak tweak detection — identifies binaries linking hooking frameworks (Substrate, Libhooker, Substitute, ElleKit) and marks them as tweaks in the dependency graph
- FairPlay encryption detection — warns when a binary is still encrypted (App Store builds)
- App framework detection — identifies cross-platform frameworks (React Native, Expo, Flutter, Cordova, Capacitor, Xamarin/.NET MAUI, Kotlin Multiplatform, NativeScript, Titanium, Qt, Electron) and game engines (Unity, Unreal Engine, Godot, Cocos2d, GameMaker, Solar2D), plus linked system frameworks (SwiftUI, UIKit, ARKit, Metal, SceneKit, SpriteKit, RealityKit, GameKit, AppKit)
- Security scan — 14 credential/secret patterns (AWS, Google/Firebase, OpenAI, Anthropic, Slack, bearer tokens, private keys, database URIs, hardcoded passwords), also checks base64-encoded strings and scans bundle files (JS bundles, JSON configs, plists). Flags leaked build artifacts: DWARF debug info and retained debug symbols, developer source paths embedded in strings, and shipped source maps / Swift module interfaces / bitcode symbol maps
- Function attribution — security findings show which function references the flagged string (xref analysis for ARM64, ARM32/THUMB, x86_64, and x86, runs lazily only when needed)
- JSON export — export all analysis data or individual tabs, filename derived from the analysed app
- Drag-and-drop — drop files onto the window to start analysis
- Search — per-tab search with regex support and case-sensitivity toggle (Ctrl+F / Cmd+F)
- Settings — configurable options including multi-binary scanning
- Keyboard navigation — Ctrl/Cmd+F for search, Ctrl+Tab to cycle file tabs, Alt+1-9 for section tabs, arrow keys in sidebar and lists
- Copy on double-click — double-click a table cell, JSON tree value, or key/value row to copy it; Classes buttons copy on click. Every copy shows a confirmation toast
Setup & Building
Prerequisites
Install dependencies
bun install
Run in development
bun start
This builds all sources and launches the Electron app.
Build steps (manual)
# Build everything
bun run build
# Or individually:
bun run build:main # Main process (TypeScript → dist/main/)
bun run build:preload # Preload script (TypeScript → dist/preload/)
bun run build:renderer # Renderer bundle (TypeScript → dist/renderer/)
bun run build:css # Copy stylesheets to dist/renderer/
bun run build:mcp # MCP server (TypeScript → dist/mcp/)
bun run build:cli # Standalone CLI (TypeScript → dist/cli/)
Package for distribution
bun run dist # Build for current platform
bun run dist:mac # macOS (universal DMG)
bun run dist:win # Windows (NSIS installer)
bun run dist:win:portable # Windows (portable exe, no install)
bun run dist:linux # Linux (AppImage + deb)
Output goes to release/. Uses electron-builder with configuration in the "build" field of package.json.
MCP Server
AppInspect includes a standalone Model Context Protocol server that exposes the full analysis engine to AI agents. No GUI or Electron needed — it runs as a plain process over stdio.
Setup
bun install
bun run build:mcp
Configure your MCP client
Add the server to your client's MCP configuration.
Claude Code
Add to .mcp.json in a project root (project-scoped) or ~/.claude.json (global):
{
"mcpServers": {
"appinspect": {
"command": "bun",
"args": ["/absolute/path/to/AppInspect/dist/mcp/server.js"]
}
}
}
Claude Desktop (claude_desktop_config.json), Cursor, VS Code — same command + args shape in their respective MCP settings.
OpenCode
Add to ~/.config/opencode/opencode.json (or opencode.json in a project root):
{
"mcp": {
"appinspect": {
"type": "local",
"command": ["bun", "/absolute/path/to/AppInspect/dist/mcp/server.js"],
"enabled": true
}
}
}
Verify with opencode mcp list — the server should show as connected.
Available tools
| Tool | Description |
|---|---|
analyse_file |
Analyse a file (IPA, Mach-O, DEB, or .app). Must be called first. |
get_overview |
Analysis summary — header, hardening, build version, hooks, frameworks |
get_section |
Detailed data for a section (see below). Supports filter, offset, limit for large datasets. |
search |
Cross-binary search across all binaries in the loaded container |
read_hex |
Read raw hex bytes from the binary. Supports offset, length, and hexdump or raw output format. |
switch_binary |
Change the active binary (framework/extension) so later calls default to it |
get_section sections: strings, headers, libraries, symbols, classes, entitlements, infoPlist, security, files, hooks
All query tools (get_overview, get_section, search, switch_binary) accept an optional path parameter to target a specific analysis session. When omitted, they default to the last analysed file.
get_overview, get_section, and read_hex also accept an optional binary index (from overview.ipa.binaries) to query any binary in the container directly, without switch_binary changing the active one.
Example workflow
- Agent calls
analyse_filewith a path to an IPA → gets an overview summary - Agent calls
get_sectionwithsection: "security"→ sees security findings - Agent calls
get_sectionwithsection: "strings", filter: "api.example.com"→ finds matching strings - Agent calls
searchwithquery: "UIWebView", tab: "classes"→ searches across all binaries
Parallel analysis
Multiple files can be analysed concurrently (e.g. by subagents). Each analyse_file call creates an isolated session keyed by file path. Query tools target the correct session via the optional path parameter:
Subagent A: analyse_file({ path: "/tmp/App1.ipa" })
Subagent B: analyse_file({ path: "/tmp/App2.ipa" })
Subagent A: get_section({ section: "security", path: "/tmp/App1.ipa" })
Subagent B: get_section({ section: "symbols", path: "/tmp/App2.ipa" })
Notes
- All analysis runs locally, offline, with no network requests
- The app does not need to be open — the MCP server is fully standalone
- The server reads whatever local path you ask it to analyse, running with your privileges. To confine
analyse_fileto a directory tree, start it withAPPINSPECT_ALLOW_ROOT=/path/to/root. - Large sections (strings, symbols, classes, libraries) support pagination via
offsetandlimit(default: 200 items) and text filtering viafilter - Symbol entries include a
demangledfield with the readable name for Swift symbols; the originalnameis preserved as-is - Extracted IPA/DEB content is cached in
~/.appinspect/cache/so re-analysing the same file skips extraction - Settings are shared with the desktop app (
~/.appinspect/appinspect-settings.json), with sensible defaults if no settings file exists
CLI
AppInspect also ships a standalone command-line entry point for headless and scripted use (CI, batch triage). It runs under Bun with no GUI or Electron, and emits either the full analysis as JSON or the security findings as a SARIF 2.1.0 report.
Build
bun install
bun run build:cli # or: bun run build (builds everything)
Usage
bun run cli -- /path/App.ipa --sarif --out report.sarif --fail-on warning
bun run cli -- /path/App.ipa --json --section security
bun run cli -- /path/App.ipa --json --section security --section strings
bun run cli -- /path/App.ipa --json --no-pretty --out analysis.json
bun run cli -- /path/App.ipa --binary 1 --json # analyse a specific binary
appinspect <file> [options]
| Flag | Description |
|---|---|
--json |
Emit the full analysis as JSON (default) |
--sarif |
Emit a SARIF 2.1.0 report of the security findings |
--section <name> |
Limit --json output to a section (repeatable): overview, strings, headers, libraries, symbols, classes, entitlements, infoPlist, hooks, security, files |
--binary <index> |
Analyse a specific binary index instead of the main one |
--out <path> |
Write output to a file (overwrites an existing file; default: stdout) |
--no-clobber |
Refuse to overwrite an existing --out file (exits 1) |
--pretty / --no-pretty |
Pretty-print or minify JSON (default: pretty) |
--fail-on <level> |
Exit 3 when a finding at/above this severity exists: critical, warning, info, or none (default: none) |
--quiet |
Suppress progress output on stderr |
--version / --help |
Print version / usage |
Output & exit codes
The machine-readable payload goes to stdout (or --out <path>); progress goes to stderr and is suppressed by --quiet.
| Exit code | Meaning |
|---|---|
0 |
Success, or no findings at/above --fail-on |
1 |
Analysis failure |
2 |
Usage error (unknown flags, missing file) |
3 |
A finding at/above --fail-on exists |
Project structure
src/
main/ # Electron main process
analysis/ # Orchestrator, security scan engine
deb/ # DEB archive extraction
ipc/ # IPC handlers
ipa/ # IPA extraction
parser/ # Mach-O parsing (headers, load commands, strings,
# symbols, ObjC metadata, code signatures, xrefs,
# chained fixups, plists)
mcp/ # Standalone MCP server (no Electron dependency)
preload/ # Electron preload bridge
renderer/ # UI
components/ # Reusable UI components (tables, search, JSON tree, toast)
tabs/ # Tab renderers (one per analysis tab)
utils/ # Shared helpers (DOM utilities, Mach-O decoders)
shared/ # Types and IPC channel definitions
Development
Linting & Formatting
We use Biome for linting and formatting. Configuration is in biome.json.
bun run check # Lint + format check
bun run check:fix # Auto-fix issues
A pre-commit hook automatically runs check:fix, TypeScript type checking, and tests before each commit.
Testing
bun test # Run all tests
bun run typecheck # TypeScript type check only
See CONTRIBUTING.md for detailed development guidelines.
Tech stack
- Electron — desktop shell
- TypeScript — full codebase, strict mode
- Bun — bundler and package manager
- Biome — linting and formatting
- fflate — ZIP decompression (IPA extraction)
- bplist-parser / plist — binary and XML plist parsing
- @modelcontextprotocol/sdk — MCP server for AI agent integration
- swift-demangle-wasm — Swift symbol demangling (WebAssembly)
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found