Claude XCIndex
A Claude Code MCP plugin providing semantic access to Xcode's symbol index — sub-millisecond Swift/ObjC lookups without grep.
Claude XCIndex
A Claude Code MCP plugin that gives Claude semantic access to Xcode’s on-disk symbol index. Instead of falling back to grep for Swift/ObjC symbol lookups, Claude queries the real build-time index directly — sub-millisecond, semantic, and surgical.
The first Claude Code plugin to provide semantic symbol lookups for Xcode projects, packaged with skills, hooks, and a subagent for rename workflows.
The Problem
When Claude Code works on Xcode projects, it needs to find symbols, trace references, and understand dependencies. Without semantic tooling, it falls back to grep and ripgrep — and for Swift, that creates real problems:
- Textual, not semantic —
grep "User"matches comments, strings, and same-named symbols in other modules. Finding the actualUsertype requires manual filtering. - Blind to Swift semantics —
grepcan’t find protocol witnesses,@objcbridging, extensions across files, or overloaded methods. The index knows about all of them. - Slow at scale — grepping a large Xcode project can take seconds. Sub-millisecond index lookups change the interaction model entirely.
- No structural awareness — Claude can’t answer “who calls this?” or “what would break if I edit this file?” without reading half the codebase.
Technical Approach
claude-xcindex reads Xcode’s own LMDB-backed IndexStoreDB — the same index Xcode builds during compilation. No re-indexing, no daemon, no second copy of data.
The MCP server is a single compiled Swift binary that speaks MCP directly over stdio via Anthropic’s swift-sdk. No Node runtime, no intermediate process.
┌──────────────────┐ MCP/stdio ┌──────────────────┐
│ Claude Code │◀─────────────────▶│ xcindex binary │
│ │ │ (Swift 6.1) │
└──────────────────┘ └────────┬─────────┘
│
┌──────┴─────────┐
│ IndexStoreDB │
│ (LMDB-backed) │
│ Xcode writes │
└────────────────┘
Features
Eight MCP tools are available to Claude:
| Tool | Purpose |
|---|---|
find_symbol | Name-to-USR resolution with kind and file location |
find_references | Every occurrence with file, line, column, and role |
find_definition | Canonical definition site for a symbol |
find_overrides | All override implementations of a method |
find_conformances | All types conforming to a protocol |
blast_radius | Minimal set of files affected by editing a file |
status | Index freshness, DerivedData path, last-build time |
plan_rename | Semantic rename plan tiered by confidence |
Three skills trigger automatically in Claude Code when working with Swift: swift-find-references, swift-blast-radius, and swift-rename-symbol.
SessionStart and PostToolUse hooks monitor index freshness — if source files have been edited since the last Xcode build, Claude is warned about stale index data. The plugin never builds on Claude’s behalf; it surfaces the information and lets the user decide.
Current Status
| Feature | Status |
|---|---|
| find_symbol | Complete |
| find_references | Complete |
| find_definition | Complete |
| find_overrides | Complete |
| find_conformances | Complete |
| blast_radius | Complete |
| status | Complete |
| plan_rename (v2.3.0) | Complete |
| SessionStart hook | Complete |
| PostToolUse hook | Complete |
| Swift rename subagent | Complete |
| CI (semantic-release) | Complete |
| Protocol existential support | Planned |
| Cross-module rename propagation | Planned |
Learnings
- Semantic is a different category from textual — once you have the index, the questions Claude can answer change. “Find all callers of this protocol method including retroactive conformances” goes from impossible to a single tool call.
- Freshness awareness is essential for trust — the hardest problem isn’t index performance; it’s knowing whether the index is stale. The hooks that warn about unbuilt changes are what make the tools safe to rely on.
- Plugin packaging matters as much as the server — shipping skills and hooks alongside the MCP server means Claude knows when to use the tools, not just how. Without the skills, the tools sit unused because Claude defaults to
grep. - The IndexStoreDB format is stable but undocumented — Apple’s
swiftlang/indexstore-dbtracks the main branch, and the format has been stable for years. But there’s no formal spec, so staying in sync with upstream requires tracking their releases.
More projects
View all projectsFlow Forecast
Time-series forecasting API for river flow rates using Facebook Prophet, integrated with GaugeWatcher
Zustand + Chrome Storage
A pattern for using Zustand with Chrome's Storage API as a single source of truth in browser extensions
Irrigation
A distributed, Rust-powered IoT irrigation system with soil moisture telemetry, safety-first valve control, and a local web dashboard