{"_id":"@buyhatke-dev/nitpick-mcp","_rev":"3-9656836ffc844ce0d91ef51327da971f","name":"@buyhatke-dev/nitpick-mcp","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@buyhatke-dev/nitpick-mcp","version":"0.1.0","keywords":["mcp","model-context-protocol","qa","testing","ui-review","maestro","playwright","android","exploratory-testing"],"author":{"name":"Buyhatke"},"license":"MIT","_id":"@buyhatke-dev/nitpick-mcp@0.1.0","maintainers":[{"name":"keshav-kr","email":"keshavk@buyhatke.com"},{"name":"pattahgobhi","email":"aayushmaan@onramp.money"}],"homepage":"https://github.com/Buyhatke/nitpick-mcp#readme","bugs":{"url":"https://github.com/Buyhatke/nitpick-mcp/issues"},"bin":{"nitpick-mcp":"dist/index.js"},"dist":{"shasum":"b3759ad28b5bee2e46d1f98cdd51101d9492ab5b","tarball":"https://registry.npmjs.org/@buyhatke-dev/nitpick-mcp/-/nitpick-mcp-0.1.0.tgz","fileCount":24,"integrity":"sha512-i6szf/T8B/3LL/Rucyu/eVv1Lk92ukNVurWaslUvFUX6E6Z8INSvrr8p/8yzLKqi5xOIQMjG3qkQO5/NF/FVTg==","signatures":[{"sig":"MEUCIHn7+4DzuOXsd+pXHfL0z9OK4x15BUoyaXkwme5LOUpAAiEA/FkKvT/04klWcU9FuYLu6rWIX3icXRtpnFMgbpqjsso=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":130086},"type":"module","engines":{"node":">=18"},"gitHead":"25d9f108dbe9753d097b1e0a55ed220b61dad26f","scripts":{"dev":"tsc --watch","build":"tsc","clean":"rm -rf dist","start":"node dist/index.js","prepare":"npm run build","prepublishOnly":"npm run clean"},"_npmUser":{"name":"pattahgobhi","email":"aayushmaan@onramp.money"},"repository":{"url":"git+ssh://git@github.com/Buyhatke/nitpick-mcp.git","type":"git"},"_npmVersion":"11.7.0","description":"Nitpick Testing MCP — agent-agnostic exploratory UI reviewer (host-is-brain, driver abstraction, persistent .qa/ memory)","directories":{},"_nodeVersion":"24.12.0","dependencies":{"zod":"^3.23.8","yaml":"^2.5.0","@modelcontextprotocol/sdk":"^1.12.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"peerDependencies":{"playwright":"^1.40.0"},"peerDependenciesMeta":{"playwright":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/nitpick-mcp_0.1.0_1783508482310_0.0773551215385091","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@buyhatke-dev/nitpick-mcp","version":"0.2.0","description":"Nitpick Testing MCP — agent-agnostic exploratory UI reviewer (host-is-brain, driver abstraction, persistent .qa/ memory)","type":"module","license":"MIT","author":{"name":"Buyhatke"},"repository":{"type":"git","url":"git+ssh://git@github.com/Buyhatke/nitpick-mcp.git"},"homepage":"https://github.com/Buyhatke/nitpick-mcp#readme","bugs":{"url":"https://github.com/Buyhatke/nitpick-mcp/issues"},"keywords":["mcp","model-context-protocol","qa","testing","ui-review","maestro","playwright","android","exploratory-testing"],"engines":{"node":">=18"},"bin":{"nitpick-mcp":"dist/index.js"},"publishConfig":{"access":"public"},"scripts":{"clean":"rm -rf dist","build":"tsc","dev":"tsc --watch","start":"node dist/index.js","test":"npm run build && node --test test/*.test.mjs","test:unit":"npm run build && node --test test/unit.test.mjs","bench":"npm run build && node bench/run.mjs","prepare":"npm run build","prepublishOnly":"npm run clean"},"dependencies":{"@modelcontextprotocol/sdk":"^1.12.0","yaml":"^2.5.0","zod":"^3.23.8"},"peerDependencies":{"playwright":"^1.40.0"},"peerDependenciesMeta":{"playwright":{"optional":true}},"devDependencies":{"@types/node":"^22.0.0","typescript":"^5.6.0"},"gitHead":"5dff7f542864ddb39c50db79f7b43fa9aaf7a029","_id":"@buyhatke-dev/nitpick-mcp@0.2.0","_nodeVersion":"24.12.0","_npmVersion":"11.7.0","dist":{"integrity":"sha512-EpCXz2Zo7ffZJkdZDyU61q942E/qK+20Tla0/l70cfDlx/2QHHZxODd92xt8yI6GBB9mY735gH+pO4j4BvySog==","shasum":"bd5311472b6d5a74eb5f085fd568835433bfa359","tarball":"https://registry.npmjs.org/@buyhatke-dev/nitpick-mcp/-/nitpick-mcp-0.2.0.tgz","fileCount":31,"unpackedSize":235718,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAp/3jP4Y/IYzB/pfQNEQ674tHyzxjLPN1A1VX5KD3a+AiEAzedvzpX5rtRvnKl7LgOfGO1uSrereAprHRx7ANnInNQ="}]},"_npmUser":{"name":"pattahgobhi","email":"aayushmaan@onramp.money"},"directories":{},"maintainers":[{"name":"archie30","email":"archie@onramp.money"},{"name":"keshav-kr","email":"keshavk@buyhatke.com"},{"name":"pattahgobhi","email":"aayushmaan@onramp.money"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/nitpick-mcp_0.2.0_1784115632698_0.5644624798108293"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-08T11:01:21.941Z","modified":"2026-07-15T11:40:32.975Z","0.1.0":"2026-07-08T11:01:22.448Z","0.2.0":"2026-07-15T11:40:32.836Z"},"bugs":{"url":"https://github.com/Buyhatke/nitpick-mcp/issues"},"author":{"name":"Buyhatke"},"license":"MIT","homepage":"https://github.com/Buyhatke/nitpick-mcp#readme","keywords":["mcp","model-context-protocol","qa","testing","ui-review","maestro","playwright","android","exploratory-testing"],"repository":{"type":"git","url":"git+ssh://git@github.com/Buyhatke/nitpick-mcp.git"},"description":"Nitpick Testing MCP — agent-agnostic exploratory UI reviewer (host-is-brain, driver abstraction, persistent .qa/ memory)","maintainers":[{"name":"archie30","email":"archie@onramp.money"},{"name":"keshav-kr","email":"keshavk@buyhatke.com"},{"name":"pattahgobhi","email":"aayushmaan@onramp.money"}],"readme":"# Nitpick Testing MCP\n\nAgent-agnostic exploratory UI reviewer, delivered as an **MCP server**. It reviews an app\nand informs — it never changes application code.\n\n**Design:** host-is-brain (no embedded LLM — your coding agent drives), composable tools,\ndriver abstraction (Maestro for mobile, Playwright for web — both live), and persistent\nin-repo `.qa/` memory with a reconciled findings ledger.\n\n## Install & build\n\n```bash\ncd nitpick-mcp\nnpm install\nnpm run build\n```\n\nRequires: Node 18+. Prerequisites depend on the driver — run the **`doctor`** tool to check:\n- **Maestro (mobile):** just `adb` on PATH + an attached Android device — **no Android Studio**. A real\n  phone over USB (Developer options → USB debugging → accept the RSA prompt) is the lightest path. The\n  `maestro` CLI is **optional** — only `run_flow` (replaying saved flows) uses it; every interactive tool\n  drives the device through `adb` directly, so it never blocks readiness.\n- **Playwright (web):** the `playwright` package + a chromium browser — `doctor { install: true }`\n  installs both automatically (they're self-contained). System-level pieces (adb, the Maestro CLI,\n  Android SDK/AVD) are detected and reported with fix guidance, never silently installed.\n\n`start_session` runs `doctor` as a preflight and reports readiness in its envelope, so you know\nwhat's missing before any action fails.\n\n## Register with an MCP client\n\nInstall it first (see [`INSTALL.md`](./INSTALL.md) for git/tarball/source options), then register the\ninstalled `nitpick-mcp` binary. Claude Code:\n\n```bash\nclaude mcp add nitpick -- nitpick-mcp\n```\n\nOr add to any MCP client config:\n\n```json\n{ \"mcpServers\": { \"nitpick\": { \"command\": \"nitpick-mcp\" } } }\n```\n\n> Don't register `npx <git-url>` or a `.tgz` as the command — it re-installs on every launch and can\n> exceed the client's connect timeout. Install once, then point the client at the installed bin.\n\n## Use\n\n1. `start_session` with a `projectPath` (imported: code + UI), a `url` (web, link-only: UI), or an\n   `appId` (mobile black-box: installed app, UI-only; `.qa/` stored under `~/.qa-mcp/projects/<slug>/`).\n   It auto-detects platform/driver/source, creates `.qa/`, and returns a **guided envelope**\n   telling the agent whether to map or review next, with the methodology inline.\n2. First run → follow `qa_map` (index the app into `map.md` + `flows/`, draft `brief.md`).\n3. Later runs → follow `qa_review` (explore/brute-test, record findings). The agent reads\n   `qa://findings` first and reconciles; the server maintains the ledger and regenerates\n   `findings.md` with a since-last-run diff.\n\n## Surface\n\n| Kind | Names |\n|---|---|\n| Session & auth | `start_session`, `doctor`, `login`, `save_auth` |\n| Perception & interaction | `capture`, `tap`, `long_press`, `scroll`, `input`, `press`, `hover`, `focus`, `scroll_to`, `select_option`, `set_checked`, `drag`, `upload_file` |\n| Navigation & tabs | `navigate`, `open_tab`, `list_tabs`, `switch_tab`, `close_tab`, `current_page` |\n| Sync & retrieval | `wait`, `observe`, `evaluate`, `inspect_ui`, `extract_ui` |\n| State & journeys | `save_ui_state`, `compare_ui_state`, `run_flow`, `save_flow` |\n| UX & memory | `audit_ui`, `list_findings`, `record_finding`, `update_brief`, `update_map`, `export_report`, `export_data` |\n| Resources | `qa://config`, `qa://brief`, `qa://map`, `qa://flows`, `qa://flows/{name}`, `qa://findings`, `qa://review-guide`, `qa://help` |\n| Prompts | `qa_map`, `qa_review`, `help` |\n\n**v0.2.0** — general-purpose UI exploration: bounded/scoped capture with rich element state,\na multi-page registry (tabs, popups, frames, redirects, cross-domain **workspaces**), complete\ninteractions with structured results, schema-free `inspect_ui`/`extract_ui`, UI-state diffs,\nversioned journeys with assertions + retained failure evidence, deterministic `audit_ui`, and\nPDF/HTML/JSON/CSV artifacts with verified paths. All new args are optional; existing calls and\nsaved `.qa/` projects stay compatible, and ordinary traversal no longer needs `evaluate`.\nWeb-only tools return a clear capability error under the Maestro (mobile) driver.\n\n`capture()` returns the screenshot **inline as an image** (Set-of-Mark: each element outlined\nwith its id, e.g. `e13`) alongside `{ screenshot, elements[labeled], errors, size }`. Act by\n**label** or **id**, not coordinates: `tap(\"Continue\")` / `tap(\"e13\")` and the driver resolves it.\nToggle with `capture({ annotate: false })` / `capture({ image: false })`. (Set-of-Mark overlay is\nweb-only today; inline image works for both drivers.)\n\n## Memory layout (`.qa/`)\n\n```\nconfig.yaml   brief.md   map.md   flows/   findings.md   findings.json\nstates/   reports/   runs/   evidence/\n```\n\nCommitted: `config.yaml`, `brief.md`, `map.md`, `flows/` (incl. `*.journey.json`), `findings.*`.\nGit-ignored (via shipped `.qa/.gitignore`): `config.local.yaml`, `evidence/`, `states/`, `reports/`, `runs/`, `logs/`, `.cache/`.\nLink-only mode stores `.qa/` under `~/.qa-mcp/projects/<slug>/`; an opt-in `workspace:` groups a\ncross-domain audit under `~/.qa-mcp/workspaces/<name>/` instead.\n\n## Drivers\n\nBoth drivers implement the same neutral `Driver` core (`capture`/`tap`/`input`/`press`/`scroll`/\n`runFlow`/`observe` + a `capabilities()` report). Browser-only powers (page registry, `navigate`,\n`inspect_ui`, `extract_ui`, `audit_ui`, structured telemetry) are **optional** methods gated by\n`capabilities()`, so Maestro is never forced to fake browser concepts and web-only tools fail with a\nclear capability message under mobile.\n- **`maestro`** (mobile) — ADB screenshot + uiautomator hierarchy; taps resolve label→coordinate.\n- **`playwright`** (web) — persistent Chromium; taps resolve label→Locator via a per-capture\n  `data-nitpick-id` tag (robust to layout shifts); console/network errors buffered for `observe`;\n  web flows are a neutral JSON step list; auth via `storageState` referenced from `config.local.yaml`.\n\n`start_session` auto-selects the driver, or set `driver:` in `.qa/config.yaml`.\n\n## Auth (getting past login)\n\nMost real apps need a login first. Configure it in the git-ignored `.qa/config.local.yaml`:\n\n```yaml\nauth:\n  loginFlow: login          # a saved flow in .qa/flows that logs in\n  credentials: { username: you@example.com, password: secret }\n  headed: false             # true = visible browser for manual OTP/2FA/SSO\n```\n\n- **Automatable login** — put `{{username}}`/`{{password}}` placeholders in the committed `login`\n  flow (no secrets in it); call `login()`. Creds are injected at runtime; the session is saved to\n  `.qa/.cache/auth-state.json`.\n- **OTP / 2FA / SSO** — set `headed: true`, log in by hand once, call `save_auth()`.\n- Future `start_session` calls **reuse the saved session** and start already logged in.\n\nSecrets (`config.local.yaml`) and the saved session (`.qa/.cache/`) are git-ignored.\n\n## Review ideology\n\n`REVIEW.md` is the base review prompt (the *how to think*). `qa_review` composes it with the\nper-project `brief.md` (the *what to care about*). Edit `REVIEW.md` to tune the philosophy for\nevery review; it reloads without a rebuild and is exposed as the `qa://review-guide` resource.\n","readmeFilename":"README.md"}