# Ravel MCP server

Ravel's MCP server lets AI assistants and agents query the Ravel catalogue of Apple firmware builds. Every tool only reads the catalogue, needs no account or token, and is rate limited.

This is the Markdown version of https://ravel.dbg.re/docs/mcp.

## Endpoint

- URL: `https://ravel.dbg.re/mcp`
- Transport: Streamable HTTP.
- Authentication: none.

## Connect

Claude Code adds the server with one command.

```sh
claude mcp add --transport http ravel https://ravel.dbg.re/mcp
```

Codex CLI, the IDE extension, and the app read it from `~/.codex/config.toml`.

```toml
[mcp_servers.ravel]
url = "https://ravel.dbg.re/mcp"
```

VS Code reads it from `.vscode/mcp.json`.

```json
{
  "servers": {
    "ravel": {"type": "http", "url": "https://ravel.dbg.re/mcp"}
  }
}
```

Cursor reads it from `~/.cursor/mcp.json`.

```json
{
  "mcpServers": {
    "ravel": {"url": "https://ravel.dbg.re/mcp"}
  }
}
```

Clients that add remote servers by URL take the endpoint as is. Clients that only start local servers reach it through `mcp-remote`.

```sh
npx -y mcp-remote https://ravel.dbg.re/mcp
```

## Using the tools

Ravel is a read-only catalogue of Apple firmware builds. It holds Mach-O binaries, dyld shared cache images, and kernelcache entries, with the kernel as com.apple.kernel and each kernel extension under its bundle identifier in the kernelcache domain. Every binary carries its exports, imports, dependencies, segments, sections, C strings, Objective-C API, entitlements, plist properties, and code identities. The kernelcache com.apple.security.sandbox entry also carries the compiled Seatbelt profiles and their decompiled SBPL rules, each rule owned by its profile as origin, and macOS .sb profile files are binaries whose records are their SBPL lines. Kernelcache KEXTs without code are binaries whose records are their prelink Info.plist properties. Start with list_builds, because every build-scoped tool takes a build token from it. search_binaries, search_records, and search_entitlements search across builds. Use lookup_build_binary and query_binary_facts to inspect one binary by domain and logical path. compare_builds, compare_binary, and compare_entitlements report differences between two builds. Omit base and target to compare the latest compatible pair. triage_patch ranks the changed binaries most likely to carry each fix named in an Apple security advisory, given its component headings, and lists changed binaries no component explains. list_advisories lists Apple's security advisories with the catalogue build pairs each one matches, and triage_patch takes an advisory id from it in place of component headings. Results are paged with offset and limit. Failed calls return a JSON error code. Narrow the query after query_too_large, wait as long as a busy error says before retrying, and retry after a pause on unavailable.

Each tool returns its result as JSON text.

## Tools

### `list_builds`

List builds in catalogue order.

#### Arguments

None.

### `get_build`

Get a build by its exact public token.

#### Arguments

- `build` (string, required): Exact public build token.

### `list_build_binaries`

List binaries in a build.

#### Arguments

- `build` (string, required): Exact public build token.
- `offset` (integer, optional, default 0 · minimum 0): Zero-based result offset.
- `limit` (integer, optional, default 25 · minimum 1 · maximum 200): Page size.

### `list_build_record_classes`

List record collections and availability.

#### Arguments

- `build` (string, required): Exact public build token.

### `list_build_records`

Browse one record collection in a build.

#### Arguments

- `build` (string, required): Exact public build token.
- `class` (string, required): Record collection returned by the build record-classes resource.
- `offset` (integer, optional, default 0 · minimum 0): Zero-based result offset.
- `limit` (integer, optional, default 25 · minimum 1 · maximum 200): Page size.

### `lookup_build_binary`

Resolve an exact binary locator.

#### Arguments

- `build` (string, required): Exact public build token.
- `domain` (string, required): Exact source domain.
- `path` (string, required): Exact logical binary path.

### `query_binary_facts`

Query facts for an exact binary locator. direction must be absent when sort is absent. detail filtering and sorting are valid only for entitlement, plist_entry, and sandbox_profile classes. The address of a sandbox_rule or sandbox_source fact is its line number in SBPL text, still encoded as a hexadecimal address, so sort=address with one profile's exact origin returns that profile's SBPL in order.

#### Arguments

- `build` (string, required): Exact public build token.
- `domain` (string, required): Exact source domain.
- `path` (string, required): Exact logical binary path.
- `class` (string, optional): Optional record class, trimmed and limited to 256 UTF-8 bytes.
- `query` (string, optional): Optional text after trimming, at most 256 UTF-8 bytes.
- `filter_collection` (string, optional): Case-insensitive collection filter, trimmed and limited to 256 UTF-8 bytes. A value wrapped in double quotes must match the whole column.
- `filter_value` (string, optional): Case-insensitive value filter, trimmed and limited to 256 UTF-8 bytes. A value wrapped in double quotes must match the whole column.
- `filter_origin` (string, optional): Case-insensitive origin filter, trimmed and limited to 256 UTF-8 bytes. A value wrapped in double quotes must match the whole column, so filter_origin="collection/com.apple.sandboxd" with class=sandbox_rule selects one sandbox profile's rules.
- `filter_detail` (string, optional): Case-insensitive projected detail filter, trimmed and limited to 256 UTF-8 bytes. A value wrapped in double quotes must match the whole column.
- `filter_address` (string, optional): Case-insensitive rendered address filter, trimmed and limited to 256 UTF-8 bytes. Addresses render as hexadecimal, except sandbox_rule and sandbox_source line numbers, which render as decimal. A value wrapped in double quotes must match the whole column.
- `filter_count` (string, optional): Case-insensitive rendered count filter, trimmed and limited to 256 UTF-8 bytes. A value wrapped in double quotes must match the whole column.
- `sort` (string, optional, one of "collection", "value", "origin", "detail", "address", "count"): Fact sort column.
- `direction` (string, optional, default "asc" · one of "asc", "desc"): Sort direction. Defaults to asc when sorting applies.
- `offset` (integer, optional, default 0 · minimum 0): Zero-based result offset.
- `limit` (integer, optional, default 25 · minimum 1 · maximum 200): Page size.

### `list_entitlement_holders`

Page exact entitlement holders in a build. Exact, case-sensitive top-level key lookup across all indexed domains, deduplicated by binary and canonical value. Key is trimmed and limited to 256 UTF-8 bytes. Order is domain, logical path, binary identity, then value. To continue comparison previews, page from offset zero and retain domains in the comparison's common_coverage. This endpoint may also include domains outside the comparison.

#### Arguments

- `build` (string, required): Exact public build token.
- `key` (string, required): Exact case-sensitive entitlement key.
- `offset` (integer, optional, default 0 · minimum 0): Zero-based result offset.
- `limit` (integer, optional, default 25 · minimum 1 · maximum 200): Page size.

### `search_binaries`

Search binary logical paths across builds.

#### Arguments

- `query` (string, required): Nonempty text after trimming, at most 256 UTF-8 bytes.
- `limit` (integer, optional, default 25 · minimum 1 · maximum 200): Maximum number of ranked results.

### `search_records`

Search record values across builds. Matches indexed record values and the code-signing identifiers of code identities, whose indexed value is the CodeDirectory hash. contains mode requires at least three Unicode characters after trimming.

#### Arguments

- `query` (string, required): Nonempty text after trimming, at most 256 UTF-8 bytes.
- `mode` (string, optional, default "prefix" · one of "prefix", "exact", "contains"): Record search mode.
- `limit` (integer, optional, default 25 · minimum 1 · maximum 200): Maximum number of ranked results.

### `search_entitlements`

Search entitlement records.

#### Arguments

- `query` (string, required): Nonempty text after trimming, at most 256 UTF-8 bytes.
- `offset` (integer, optional, default 0 · minimum 0): Zero-based result offset.
- `limit` (integer, optional, default 25 · minimum 1 · maximum 200): Page size.

### `compare_builds`

Compare complete builds. base and target must be supplied together. When both are absent, the latest compatible pair is selected.

#### Arguments

- `base` (string, optional): Baseline public build token. Must be paired with target.
- `target` (string, optional): Target public build token. Must be paired with base.
- `domain` (string, optional): Optional exact source domain, trimmed and limited to 256 UTF-8 bytes.
- `status` (string, optional, one of "surface", "content", "metadata", "unchanged", "added", "removed"): Build component change classification.
- `class` (string, optional): Optional record class, trimmed and limited to 256 UTF-8 bytes.
- `query` (string, optional): Optional text after trimming, at most 256 UTF-8 bytes.
- `hide_content` (boolean, optional, default true): Hide non-semantic content-only changes. Only lowercase true or false is accepted.
- `filter_change` (string, optional): Case-insensitive rendered change filter, trimmed and limited to 256 UTF-8 bytes.
- `filter_domain` (string, optional): Case-insensitive source-domain filter, trimmed and limited to 256 UTF-8 bytes.
- `filter_path` (string, optional): Case-insensitive logical-path filter, trimmed and limited to 256 UTF-8 bytes.
- `filter_version` (string, optional): Case-insensitive binary-version filter, trimmed and limited to 256 UTF-8 bytes.
- `filter_size` (string, optional): Case-insensitive rendered size filter, trimmed and limited to 256 UTF-8 bytes.
- `filter_records` (string, optional): Case-insensitive rendered record-count filter, trimmed and limited to 256 UTF-8 bytes.
- `filter_collections` (string, optional): Case-insensitive changed-collection filter, trimmed and limited to 256 UTF-8 bytes.
- `sort` (string, optional, default "change" · one of "change", "domain", "path", "version", "size", "records", "collections"): Build component sort column.
- `direction` (string, optional, default "asc" · one of "asc", "desc"): Sort direction. Defaults to asc when sorting applies.
- `offset` (integer, optional, default 0 · minimum 0): Zero-based result offset.
- `limit` (integer, optional, default 25 · minimum 1 · maximum 200): Page size.

### `compare_binary`

Compare one binary across builds. base and target must be supplied together. When both are absent, the latest compatible pair is selected. An ambiguous path returns candidate source domains.

#### Arguments

- `base` (string, optional): Baseline public build token. Must be paired with target.
- `target` (string, optional): Target public build token. Must be paired with base.
- `domain` (string, optional): Optional exact source domain, trimmed and limited to 256 UTF-8 bytes.
- `path` (string, required): Exact logical binary path.
- `class` (string, optional): Optional record class, trimmed and limited to 256 UTF-8 bytes.
- `change` (string, optional, one of "updated", "added", "removed"): Exact record change type.
- `hide_content` (boolean, optional, default true): Hide non-semantic content-only changes. Only lowercase true or false is accepted.
- `offset` (integer, optional, default 0 · minimum 0): Zero-based result offset.
- `limit` (integer, optional, default 25 · minimum 1 · maximum 200): Page size.

### `compare_entitlements`

Compare entitlements across builds. base and target must be supplied together. When both are absent, the latest compatible pair is selected. query matches entitlement keys or changed holder domains, paths, and values before pagination. Unchanged holders do not produce a match. Each entry's base and target arrays preview at most holders_limit (100) holders in shared complete domains, including unchanged holders, ordered by domain, logical path, and canonical value. base_total and target_total are exact. Retrieve complete evidence through list_entitlement_holders with the entry key, paging from offset zero and retaining common_coverage domains. Its pages include all indexed domains.

#### Arguments

- `base` (string, optional): Baseline public build token. Must be paired with target.
- `target` (string, optional): Target public build token. Must be paired with base.
- `query` (string, optional): Optional text after trimming, at most 256 UTF-8 bytes.
- `offset` (integer, optional, default 0 · minimum 0): Zero-based result offset.
- `limit` (integer, optional, default 25 · minimum 1 · maximum 200): Page size.

### `list_advisories`

List Apple security advisories with their catalogue build pairs. Every update on Apple's security releases page (support.apple.com/en-us/100100), newest release first, as last read. Each advisory carries its fix and CVE counts, component names, and pairs: per device, the catalogue build of the advisory's release and the earlier comparable build it is triaged against. catalogue_state says why an advisory has no complete pair. Pass id as advisory to triage_patch to rank the changed binaries, or to get_advisory for Apple's entries.

#### Arguments

- `family` (string, optional, one of "iOS", "macOS", "iPadOS", "watchOS", "tvOS", "visionOS", "Safari", "Xcode", "Other"): Only advisories naming this family. Other covers products outside the listed families.
- `offset` (integer, optional, default 0 · minimum 0): Zero-based result offset.
- `limit` (integer, optional, default 25 · minimum 1 · maximum 200): Page size.

### `get_advisory`

Get one Apple security advisory with its entries. The advisory as listed by list_advisories, plus every entry Apple published: component, impact, description, CVE identifiers, and Entry added or updated notes.

#### Arguments

- `advisory` (string, required): Advisory id, Apple's support document number or the listed slug.

### `triage_patch`

Triage a security advisory against a build comparison. Ranks the binaries that changed between two builds against the components of an Apple security advisory. Pass an advisory id from list_advisories in advisory, which triages Apple's components and returns its entries with each component; without base and target its first matched pair is used, and an advisory without one answers 409. Alternatively pass component headings such as Kernel, ImageIO, or WebKit in components. base and target must be supplied together; with components and neither, the latest compatible pair is selected. Only domains in common_coverage are considered. Each component lists up to 20 changed binaries, highest score first, matched by executable or bundle name, by a curated alias table (Kernel is kernelcache com.apple.kernel, WebKit includes WebCore and JavaScriptCore), by its leading words one confidence level lower (WebKit Canvas matches WebKit), or by fuzzy name overlap at low confidence. A score is the sum of its factors: change tier, size delta, changed record collections, and the match bonus; factors named noise score 0. A binary with only noise has change noise, always counts in noise_matches rather than changed_matches, and is listed only while hide_content is false. A KEXT without code is noise only when its Info.plist changed in nothing but build versions, build paths, and build identifiers, since its plist is its whole surface. unexplained pages by offset and limit through changed binaries without a high- or medium-confidence match, highest score first: candidates for silent fixes. Inspect any result with compare_binary using its compare_binary arguments.

#### Arguments

- `advisory` (string, optional): Advisory id, Apple's support document number or the listed slug. Its components and Apple's entries are triaged; without base and target its first matched pair is used.
- `base` (string, optional): Baseline public build token. Must be paired with target.
- `target` (string, optional): Target public build token. Must be paired with base.
- `components` (string, optional): Comma-separated advisory component names, matched case-insensitively and limited to 256 UTF-8 bytes, such as Kernel, ImageIO, WebKit. An item may carry CVE identifiers in parentheses, echoed back in cves: Kernel (CVE-2026-65343 CVE-2026-65349). Repeated names merge. Required unless advisory is given, and rejected with it.
- `hide_content` (boolean, optional, default true): Hide non-semantic content-only changes. Only lowercase true or false is accepted.
- `offset` (integer, optional, default 0 · minimum 0): Zero-based result offset.
- `limit` (integer, optional, default 25 · minimum 1 · maximum 200): Page size.

## Errors

- Requests over the rate limit get HTTP 429 with a `Retry-After` header.
- A failed tool call returns its error as JSON text and is marked `isError`. `bad_request` names the argument to fix, `query_too_large` asks for a narrower query, `busy` says how long to wait before retrying, and `unavailable` can be retried after a pause.

## Privacy

Rate limiting counts requests per network address, as described at https://ravel.dbg.re/privacy#privacy-rate-limits.
