# MachOKitMCP

> MCP server that exposes MachOKit to LLM-driven agents

- **Type:** MCP server
- **Install:** `agentstack add mcp-swiftbin-machokitmcp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [swiftbin](https://agentstack.voostack.com/s/swiftbin)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [swiftbin](https://github.com/swiftbin)
- **Source:** https://github.com/swiftbin/MachOKitMCP

## Install

```sh
agentstack add mcp-swiftbin-machokitmcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# MachOKit MCP Server

`machokit-mcp` is an [MCP](https://modelcontextprotocol.io/) server that
exposes [MachOKit](https://github.com/p-x9/MachOKit) to LLM-driven agents
(Claude Code, Claude Desktop, etc.) over stdio. It is implemented in Swift
on top of the [official MCP Swift SDK](https://github.com/modelcontextprotocol/swift-sdk).

## Build

```sh
swift build -c release
```

The product is an executable named `machokit-mcp`. Its absolute path is
`MachOKitMCP/.build/release/machokit-mcp` after the release build.

Platforms: macOS 13+. The package itself builds on Linux too, but every
loaded-image tool returns an error there because the underlying `_dyld_*`
APIs are Darwin-only. File- and cache-based tools work cross-platform.

## Register with Claude Code

Add an entry to `~/.config/claude/mcp.json` (or to a project-level MCP
config). Use the absolute path to the binary:

```jsonc
{
  "mcpServers": {
    "machokit": {
      "command": "/absolute/path/to/MachOKitMCP/.build/release/machokit-mcp"
    }
  }
}
```

Restart Claude Code. The server should appear and expose the tools listed
below.

## Tools

All tools accept a `format` argument with values `"json"` (default,
compact JSON) or `"text"` (pretty-printed JSON). List-returning tools
accept `limit` and `offset` for pagination.

Tools that inspect a single Mach-O accept a target chosen via:

- `path` — absolute file path. For fat / universal binaries add `arch`
  (e.g. `"arm64"`, `"x86_64"`, `"arm64e"`).
- `image_name` — Darwin only; matches dyld's substring lookup against
  loaded images.
- `image_index` — Darwin only; 0-based index into the current process's
  loaded images.

### Mach-O — basic

| Tool                  | Purpose                                           |
| --------------------- | ------------------------------------------------- |
| `macho_info`          | One-shot summary (header + flags + UUID + deps)   |
| `macho_header`        | Header fields only                                |
| `macho_load_commands` | LC list with type, size, offset, summary, and detailed payload fields |
| `macho_segments`      | Segments and their sections                       |
| `macho_dependencies`  | LC_LOAD_DYLIB / LC_REEXPORT / weak / lazy / upward |
| `macho_rpaths`        | LC_RPATH entries                                  |
| `macho_uuid`          | LC_UUID                                           |
| `macho_version`       | LC_SOURCE_VERSION / LC_VERSION_MIN_* / LC_BUILD_VERSION / LC_MAIN |
| `macho_info_plist`    | Embedded `__TEXT,__info_plist`                    |

### Mach-O — symbols & strings

| Tool                      | Purpose                                              |
| ------------------------- | ---------------------------------------------------- |
| `macho_symbols`           | Symbol table entries (paginated)                     |
| `macho_indirect_symbols`  | Indirect symbol table                                |
| `macho_strings`           | C strings from string-literal sections               |
| `macho_ustrings`          | UTF-16 strings from `__ustring`                      |
| `macho_cfstrings`         | `__cfstring` entries with resolved string contents   |
| `macho_exports`           | Export trie                                          |
| `macho_imports`           | Deduplicated import list (combines bind/lazy/weak)   |
| `macho_bindings`          | Raw bind / lazy / weak / classic / classic-lazy lists |
| `macho_rebases`           | Rebase operations expanded                           |
| `macho_lookup_symbol`     | Find a symbol by name (mangled or demangled)         |

### Mach-O — advanced

| Tool                          | Purpose                                       |
| ----------------------------- | --------------------------------------------- |
| `macho_function_starts`       | LC_FUNCTION_STARTS expansion                  |
| `macho_code_signature`        | Code directories, entitlements (as JSON)      |
| `macho_dyld_chained_fixups`   | Chained fixup header, segments, imports       |
| `macho_relocations`           | External relocations                          |

### Fat / universal

| Tool          | Purpose                                       |
| ------------- | --------------------------------------------- |
| `fat_inspect` | Architectures in a fat binary (cputype, offset, size, align) |

### Dyld shared cache

These tools take a `path` to a cache file. `include_subcaches` widens the
view to a `FullDyldCache` for tools that support it.

| Tool                    | Purpose                                         |
| ----------------------- | ----------------------------------------------- |
| `dyld_cache_info`       | Header (uuid, type, platform, OS, image count)  |
| `dyld_cache_mappings`   | Mapping table                                   |
| `dyld_cache_images`     | List of images in the cache (path, address)     |
| `dyld_cache_subcaches`  | Subcache table                                  |
| `dyld_cache_image_info` | Open a single image (by `image_path`) as a Mach-O |

### Loaded process (Darwin only)

| Tool                       | Purpose                                  |
| -------------------------- | ---------------------------------------- |
| `loaded_images_list`       | Iterate `_dyld_image_count` images       |
| `loaded_image_info`        | Full summary for one loaded image        |
| `loaded_dyld_cache_info`   | Mapped shared cache for current process  |

## Manual smoke test (no MCP client)

The stdio transport speaks newline-delimited JSON-RPC. After the standard
`initialize` handshake you can call any tool:

```sh
(
  printf '%s\n' \
    '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}' \
    '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
    '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"macho_info","arguments":{"path":"/bin/ls","arch":"arm64","format":"text"}}}'
  sleep 2
) | ./.build/release/machokit-mcp
```

## Output format notes

Currently, both `format=json` and `format=text` return JSON; the only
difference is whether it is compact or pretty-printed. Field labels mirror
C constants (e.g. `MH_EXECUTE`, `LC_SEGMENT_64`, `S_REGULAR`,
`CPU_TYPE_ARM64`) so that the data is directly cross-referenceable with
Apple's open-source headers.

## Release

Release commits should update the Swift server version before tagging:

```sh
scripts/release.sh 0.3.0
```

The script requires a clean working tree, updates
`Sources/MachOKitMCP/Version.swift`, runs build verification, commits the
version bump, and creates an annotated tag with the same bare SemVer string.

`macho_load_commands` keeps the compact top-level fields (`type`, `size`,
`offset`, `summary`) and adds `fields` for command-specific payload values.
Where MachOKit exposes decoded values, the tool prefers those decoded values
and includes the underlying integer value in parentheses for enums and bitsets
where unknown values matter. Segment protections and flags are expanded to
constant names, dylib/runpath/dylinker strings are extracted,
platforms/tools/thread flavors are enum-decoded, version fields include
components, and linkedit/dyld ranges include computed end offsets.

## Limitations

- Read-only. No writeback to binaries, no cache extraction to disk.
- File-based tools require an absolute path. Symlinks are followed by the
  underlying file APIs.
- `loaded_*` tools only work in the server's own process — they cannot
  introspect another running process.
- The `MachOImage` enumeration depends on `_dyld_*`, so on Linux these
  tools always error out.

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [swiftbin](https://github.com/swiftbin)
- **Source:** [swiftbin/MachOKitMCP](https://github.com/swiftbin/MachOKitMCP)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-swiftbin-machokitmcp
- Seller: https://agentstack.voostack.com/s/swiftbin
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
