sherlock
Profiles Android apps on devices or emulators via adb, measuring startup, CPU, memory (RSS/PSS), network, and interaction markers.
Profiles C and C++ binaries, capturing startup call stacks, CPU, memory, and hot functions with demangled symbols.
Profiles Electron apps including the webview and helper processes, measuring startup, CPU, memory, GPU, network, and interactions.
Profiles iOS apps in the booted Simulator, capturing launch-to-main-thread-quiet startup, CPU, memory footprint, call stacks, and interactions.
Profiles native Linux applications and process trees, measuring startup, CPU, RSS memory, memory bandwidth via perf LLC misses, network namespace, and interactions.
Profiles native macOS applications and process trees, measuring startup phases, CPU, memory footprint, GPU utilization, per-process network, and call stacks.
Profiles Node.js applications and dev servers, tracking startup, CPU, memory, network, and interactions across the process tree.
Profiles Python applications and dev servers, tracking startup, CPU, memory, network, and interactions across the process tree.
Profiles Rust binaries and Rust compiled to WebAssembly, capturing startup call stacks, CPU, memory, and hot functions with demangled symbols.
Profiles Swift binaries and native Apple apps, capturing startup call stacks, CPU, memory, and hot functions.
Profiles Tauri apps including the webview and helper processes, measuring startup, CPU, memory, GPU, network, and interactions.
Profiles WebAssembly running in the browser, including .wasm loads and long tasks from Chrome DevTools traces.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@sherlockwhy is the cold start of the release build slow?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Every time an app is slow to start or heavy to run, someone builds a one-off harness for that one repo: launch it, poll some numbers, eyeball a chart, guess. Sherlock replaces the harness. An agent reads the project, works out what it is and how to run it, launches a release build with a ready signal, samples the whole process tree every 100 ms, captures where the startup time went, and keeps watching while you click through the app. Mark an interaction and repeat it, and Sherlock tells you how much memory each one keeps.
The measuring is a small, dependency-free Node engine built on the tools your OS already ships (ps, footprint, sample, nettop, /proc, perf, simctl, adb, the Chrome DevTools Protocol). The judgment is Claude: which scenario to run, which numbers matter, which line of your code caused them.
Quick start
In Claude Code:
/plugin marketplace add hiftikha/sherlock
/plugin install sherlock@sherlockThen, in any project:
/sherlock:profile why is the cold start of the release build slow?Or without Claude Code installed first, from any project folder:
npx sherlock-profiler # from npm
npx github:hiftikha/sherlock # or straight from this repositoryThe wizard detects the project, then offers to open Claude Code with Sherlock loaded, run the agent in the terminal with your API key, profile it directly without an agent, or install the plugin for every project.
Related MCP server: flameox
Gallery
The dashboard is one local page that updates as the app runs. Numbers animate with NumberFlow, the right rail collapses (]), m marks an interaction, and every run is saved as a JSON report plus a standalone HTML page you can send to someone.
What it measures
Native (macOS) | Native (Linux) | Web (Chrome) | iOS Simulator | Android | |
Startup | spawn → first output → ready → idle | same | TTFB, FCP, LCP, load, CLS | launch → main thread quiet |
|
Where startup went | call stacks from the first instruction ( | — | long tasks from a DevTools trace, script, layout and style time, slowest requests, | call stacks ( | — |
CPU | process tree, 100 ms | process tree, | browser process tree | app process |
|
Memory | physical footprint (dirty + compressed) | RSS | JS heap + browser tree | footprint | RSS and PSS |
Memory bandwidth | not exposed without sudo |
| — | — | — |
GPU | whole-GPU utilization ( | — | — | — | — |
Network | per process ( | network namespace | request weight | — | app namespace |
Interactions | marks + per-interaction memory | same | — | same | same |
A metric Sherlock can't measure on a target is shown as unavailable with the reason, never as a flat line or a guess.
It works on anything that runs as a process: Rust, Go, Swift, C and C++ binaries, Tauri and Electron apps (the webview and helper processes are in the tree), Node, Python, dev servers, and Rust compiled to WebAssembly in the browser.
Install
Pick one way in:
Command | What you get | |
Claude Code plugin |
| The |
npx wizard |
| Detects the project and runs a drill pass, with or without an agent |
npx, straight from GitHub |
| The same, from the latest commit on |
Global CLI |
|
|
Plugin for one session |
| Load a local clone without installing |
claude plugin marketplace add hiftikha/sherlock
claude plugin install sherlock@sherlockor let the CLI do both: npx sherlock-profiler install.
Usage
In Claude Code
/sherlock:profile
/sherlock:profile the dev server takes 8 seconds to come up
/sherlock:profile memory after opening five documents
/sherlock:profile compare cold start before and after my changeYou don't have to name the skill. Claude also uses Sherlock when you ask why an app is slow to start, uses too much memory, or leaks after an interaction. A drill pass goes: detect the project, profile a release build with a ready signal, open the dashboard, read the startup phases and hot functions and find them in your code, drive two or three interactions three times each, write the findings into the dashboard, and save the report under .sherlock/.
As an agent in your terminal
export ANTHROPIC_API_KEY=...
npx sherlock-profiler agent "why does the app take 2 seconds to show a window?"The agent runs on claude-opus-5-5 with the same playbook and tools as the plugin, plus read_file, search_code and run_command. It asks before running any command or launching anything. --yes skips the questions.
Without an agent
sherlock launch --ready-log 'listening on' -- ./target/release/server
sherlock launch --ready-port 3000 -- npm run dev
sherlock attach my-app # by name or pid
sherlock web http://localhost:3000/ --throttle 4
sherlock ios com.example.app # the booted Simulator
sherlock android com.example.app # a device or emulator
sherlock detect # what is this project?
sherlock report .sherlock/sherlock-1a2b3c4d.jsonWhile a launch or attach is live, type a label and press enter to mark an interaction, or press enter alone to stop and save the report. --json prints a machine-readable digest, --exit stops after startup, --no-ui skips the dashboard.
How it works
src/platform/host.mjssamples a process tree. On macOS:psfor CPU time,footprintfor memory,ps -Mfor threads,nettopfor network,ioregfor the GPU. On Linux:/proc/<pid>/{stat,status,io,net/dev}and, whenperfis allowed, LLC miss counters for memory bandwidth. CPU is computed from cumulative CPU time between samples, so it's exact for short spikes rather than a decayed average.src/launch.mjslaunches the app and times its phases: spawn, first output, a ready signal (a log line, a port, a URL) and the CPU going quiet. On macOS a separate warm-up launch captures call stacks from the first instruction withsample -wait, because attaching a sampler freezes the process for a few hundred milliseconds and would distort the timed run.src/platform/web.mjsdrives headless Chrome over the DevTools Protocol with no Puppeteer: navigation timing, paint and LCP observers, a timeline trace for long tasks, runtime metrics, and the browser's own process tree.src/platform/mobile.mjscold-launches iOS apps withsimctland samples the Simulator process on the Mac, and Android apps witham start -Wand/procoveradb.src/findings.mjsturns samples into findings: wait-bound vs CPU-bound startup, the hot function, main-thread-bound work, memory each repeated interaction keeps, steady growth, and idle CPU.src/mcp.mjsandsrc/tools.mjsexpose all of it as 13 MCP tools. The plugin's.mcp.jsonruns it withnode, no install step.skills/profile/SKILL.mdis the playbook Claude follows for a drill pass. The terminal agent (src/agent.mjs) uses the same file as its system prompt.ui/is the dashboard: plain HTML, CSS and JavaScript fed by server-sent events from a server bound to127.0.0.1.
sherlock/
├── .claude-plugin/ plugin.json and marketplace.json
├── .mcp.json the MCP server the plugin starts
├── skills/profile/ the drill-pass playbook (/sherlock:profile)
├── cli/sherlock.mjs the CLI and npx wizard
├── src/
│ ├── platform/ host (macOS, Linux), web, mobile samplers
│ ├── parse/ pure parsers for every tool's output
│ ├── launch.mjs launch, attach, startup phases, stacks
│ ├── findings.mjs rules that turn samples into findings
│ ├── tools.mjs the tool layer shared by MCP and the agent
│ ├── mcp.mjs stdio MCP server
│ ├── agent.mjs terminal agent on the Claude API
│ └── server.mjs dashboard server and HTML reports
├── ui/ the dashboard
├── test/ unit tests per platform, integration tests, fixtures
└── docs/ the websitePrivacy and what it runs
Sherlock runs only on your machine. It starts the commands you or the agent choose (the terminal agent asks first), reads process information with the system tools listed above, and serves the dashboard on 127.0.0.1. The dashboard page loads its fonts from Google Fonts and NumberFlow from jsDelivr; without network it falls back to system fonts and plain numbers. The terminal agent sends your goal, tool results and the files it reads to the Claude API using your key. The plugin itself makes no network calls; Claude Code's own model calls are covered by your Claude Code settings. Reports are written to .sherlock/ in the project.
Limits
Memory bandwidth on macOS isn't measured. Apple exposes it only through
sudo powermetrics, and Sherlock never runs sudo. On Linux it's an estimate from last-level cache misses and needsperfwithperf_event_paranoid≤ 1.macOS GPU is the whole GPU, not your process. It's still useful for seeing a render spike line up with an interaction.
Startup on macOS is a warm start when call stacks are on, because the warm-up launch runs first. Pass
--no-stacksfor a launch with nothing before it. Neither is a true cold start after a reboot.iOS Simulator timings run on your Mac's CPU. Use them to compare builds, not as device numbers.
Linux call stacks and Android memory bandwidth aren't wired up yet.
Interactions are marked, not captured. Sherlock doesn't hook your app's input events; you, the agent or a script mark them. End-to-end interaction latency (input → frame) is the next milestone.
Requirements
Needed for | Notes | |
Node.js 22+ | everything | No runtime dependencies for profiling. |
macOS or Linux | native profiling | Windows isn't supported yet. |
the plugin and the wizard's Claude Code mode | ||
An Anthropic API key |
| |
Chrome or Chromium | web profiling | Found in the usual places and Playwright's cache. Set |
Xcode | iOS Simulator | A booted Simulator. |
Android platform tools | Android |
|
| Linux memory bandwidth | Optional. |
Development
git clone https://github.com/hiftikha/sherlock.git && cd sherlock
npm install
npm testThe test suite has unit tests for every platform's parsers and integration tests that profile real processes: a Node app, a Rust app built with cargo, a page in headless Chrome, the iOS Simulator and Android through recorded simctl and adb stand-ins (and real ones when a Simulator is booted or a device is connected), the MCP server, the dashboard and the CLI. CI runs it on macOS and Linux. See CONTRIBUTING.md.
License
MIT © 2026 Haroon Iftikhar
This server cannot be deployed
Maintenance
Related MCP Connectors
Gain visibility into the performance, availability, and health of your apps and infrastructure.
Track errors, manage performance alerts, and configure dashboards and monitors
Monitor, troubleshoot, and optimize your technology stack with Intelligent Observability.
Investigate errors, track deployments, analyze performance, and manage application monitoring
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceEnables GPU profiling and performance analysis via NVIDIA Nsight Systems, allowing agents to profile binaries and aggregate statistics for kernels, memory copies, and NVTX ranges. It supports advanced analysis through interval tree construction and structural queries on profiling reports.5MIT
- FlicenseNot gradedqualityAmaintenanceEnables coding agents to trace, profile, and burn down hotspots in application and native code, GPU kernels, and inference stacks by turning explicit local artifacts or commands into bounded, provenance-typed runtime evidence. Exposes named analysis and capture tools over stdio with optional durable preservation, without requiring workspace setup or project configuration.-
- FlicenseNot gradedqualityAmaintenanceEnables coding agents to turn explicit artifacts or commands into bounded local runtime evidence from profilers, benchmarks, trace processors, and direct targets, with typed provenance, coverage, and optional durable preservation. It exposes analysis and capture tools for tracing, profiling, and investigating hotspots in application and native code, GPU kernels, and inference stacks.-
- FlicenseNot gradedqualityAmaintenanceEnables coding agents to trace, profile, and investigate performance hotspots in application code, native code, GPU kernels, and inference stacks by coordinating local profilers, benchmark tools, trace processors, and direct capture targets. Returns bounded, typed runtime evidence with observed inputs, provenance, coverage, and limitations, all through explicit artifact paths or commands with no workspace setup required.-