Add quick start: config generator script and onboarding docs
This commit is contained in:
parent
d0d609dd2b
commit
6f2afc2d18
|
|
@ -14,6 +14,7 @@ The server is a layered ESM TypeScript application. Dependencies flow inward: `d
|
|||
- `src/server/`: MCP request translation. `createServer.ts` assembles the MCP server, `registerOfficialTools.ts`/`registerEnhancedTools.ts` register each tool set, `toolResult.ts` maps `Result` values to MCP content.
|
||||
- `tests/`: Vitest suite. `tests/fixtures/` holds the fake launcher and fake Hopper bridge used as production seams.
|
||||
- `scripts/verify-real-hopper.mjs`: real-Hopper end-to-end verifier.
|
||||
- `scripts/print-mcp-config.mjs`: prints a ready-to-paste MCP server config with absolute paths filled in (`npm run config:print -- /path/to/binary`).
|
||||
|
||||
## Build, Test, and Development Commands
|
||||
|
||||
|
|
@ -25,6 +26,7 @@ The server is a layered ESM TypeScript application. Dependencies flow inward: `d
|
|||
- `npm run format:check`: verify Prettier formatting.
|
||||
- `npm run check`: run typecheck, lint, format:check, and tests.
|
||||
- `npm run verify:hopper`: build and run the real-Hopper verifier (requires a binary).
|
||||
- `npm run config:print -- /path/to/binary`: print a ready-to-paste MCP server config with absolute paths.
|
||||
- `HOPPER_TARGET_PATH=/path/to/binary npm start`: launch Hopper and run the built stdio MCP server.
|
||||
|
||||
## Configuration & Environment Variables
|
||||
|
|
|
|||
63
README.md
63
README.md
|
|
@ -2,7 +2,47 @@
|
|||
|
||||
A TypeScript MCP server for [Hopper Disassembler](https://www.hopperapp.com/). It preserves 31 familiar Hopper operations and adds 8 reverse-engineering workflows for Swift, Objective-C, decompilation, call graphs, cross-references, and binary summaries.
|
||||
|
||||
The server uses the modular `@modelcontextprotocol/server@2.0.0-beta.3` SDK.
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
git clone <repo-url> && cd betterBinaryMCP
|
||||
npm ci && npm run build
|
||||
```
|
||||
|
||||
Generate a ready-to-paste MCP config with absolute paths filled in:
|
||||
|
||||
```bash
|
||||
npm run config:print -- /path/to/your/binary
|
||||
```
|
||||
|
||||
Paste the output into your MCP client config (Claude Desktop, Cursor, etc.) and restart the client. That's it — the 39 tools are now available.
|
||||
|
||||
```bash
|
||||
# For a .hop database:
|
||||
npm run config:print -- /path/to/file.hop --kind database
|
||||
|
||||
# For a FAT binary that needs loader args:
|
||||
npm run config:print -- /path/to/binary --loader-args '["-l","Mach-O","--aarch64"]'
|
||||
```
|
||||
|
||||
### Set up with your agent
|
||||
|
||||
Paste this prompt into Claude, Cursor, or any MCP-capable agent to have it do the setup for you:
|
||||
|
||||
> I want to connect betterBinaryMCP (a Hopper Disassembler MCP server) to this client.
|
||||
>
|
||||
> 1. Clone the repo and run `npm ci && npm run build`.
|
||||
> 2. Run `npm run config:print -- /path/to/my/binary` to generate the MCP server config.
|
||||
> 3. Paste the output into this client's MCP config and restart.
|
||||
> 4. Verify the 39 tools are listed.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Node.js 20+** — `node --version`
|
||||
- **Hopper Disassembler 6+** on macOS — ships at `/Applications/Hopper Disassembler.app/`
|
||||
- **A binary or Hopper database** to analyze
|
||||
|
||||
Accessibility permission is **not** required. Specify loader arguments for archives that would otherwise show an architecture chooser.
|
||||
|
||||
## Architecture
|
||||
|
||||
|
|
@ -18,24 +58,9 @@ The codebase is a layered ESM TypeScript application. Dependencies flow inward:
|
|||
- `src/application/` composes official operations into the 8 enhanced tools.
|
||||
- `src/domain/` holds pure parsers and the tagged error algebra; `src/contracts/` declares the caller-visible tool schemas.
|
||||
|
||||
## Requirements
|
||||
## Manual MCP Configuration
|
||||
|
||||
- Node.js 20 or newer
|
||||
- Hopper Disassembler 6+ on macOS
|
||||
- A binary or Hopper database to analyze
|
||||
|
||||
Accessibility permission is **not** required. Specify loader arguments for archives that would otherwise show an architecture chooser.
|
||||
|
||||
## Install and Build
|
||||
|
||||
```bash
|
||||
npm ci
|
||||
npm run build
|
||||
```
|
||||
|
||||
## MCP Configuration
|
||||
|
||||
Build the project, then configure your MCP client with an absolute path:
|
||||
If you prefer to write the config by hand, build the project and use absolute paths:
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
@ -51,7 +76,7 @@ Build the project, then configure your MCP client with an absolute path:
|
|||
}
|
||||
```
|
||||
|
||||
Run it directly with `npm start` after building. Stdout is reserved for MCP protocol messages; diagnostics use stderr.
|
||||
Stdout is reserved for MCP protocol messages; diagnostics use stderr.
|
||||
|
||||
### Environment Variables
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@
|
|||
"test": "vitest run",
|
||||
"test:watch": "vitest",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"verify:hopper": "npm run build && node scripts/verify-real-hopper.mjs"
|
||||
"verify:hopper": "npm run build && node scripts/verify-real-hopper.mjs",
|
||||
"config:print": "node scripts/print-mcp-config.mjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/server": "2.0.0-beta.3",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* Print a ready-to-paste MCP server config with absolute paths filled in.
|
||||
*
|
||||
* Usage:
|
||||
* node scripts/print-mcp-config.mjs /path/to/binary
|
||||
* node scripts/print-mcp-config.mjs /path/to/binary --kind database
|
||||
* node scripts/print-mcp-config.mjs /path/to/binary --loader-args '["-l","Mach-O","--aarch64"]'
|
||||
*/
|
||||
import { resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const targetPath = process.argv[2];
|
||||
if (!targetPath) {
|
||||
process.stderr.write(
|
||||
"Usage: node scripts/print-mcp-config.mjs <target-path> [--kind executable|database] [--loader-args JSON]\n",
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const flags = process.argv.slice(3);
|
||||
const kind = readFlag(flags, "--kind") ?? "executable";
|
||||
const loaderArgs = readFlag(flags, "--loader-args");
|
||||
|
||||
const serverPath = resolve(
|
||||
fileURLToPath(new URL("..", import.meta.url)),
|
||||
"dist/main.js",
|
||||
);
|
||||
|
||||
const env = {
|
||||
HOPPER_TARGET_PATH: resolve(targetPath),
|
||||
HOPPER_TARGET_KIND: kind,
|
||||
};
|
||||
if (loaderArgs) env.HOPPER_LOADER_ARGS_JSON = loaderArgs;
|
||||
|
||||
const config = {
|
||||
mcpServers: {
|
||||
betterBinaryMCP: {
|
||||
command: "node",
|
||||
args: [serverPath],
|
||||
env,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
process.stdout.write(`${JSON.stringify(config, null, 2)}\n`);
|
||||
|
||||
function readFlag(args, name) {
|
||||
const i = args.indexOf(name);
|
||||
return i !== -1 ? args[i + 1] : undefined;
|
||||
}
|
||||
Loading…
Reference in New Issue