MCP Servers

A collection of Model Context Protocol servers, templates, tools and more.

MCP server by hmSchuller

Created 4/18/2026
Updated about 5 hours ago
Repository documentation and setup instructions

xcpv

xcpv is a Swift CLI that turns a Swift source file inside a Swift package into a persistent, reusable iOS preview host app.

It does not use Xcode's inline preview canvas. Instead, it:

  1. finds the owning Swift package,
  2. resolves the SwiftPM target and library product,
  3. parses preview declarations from the selected file,
  4. creates or reuses a cached iOS host project,
  5. rewrites only GeneratedPreviewHost.swift, and
  6. either opens the cached project, runs a full simulator build with xcodebuild, or refreshes the Simulator via a bridge-only swiftc fast path when possible.

Status

v1 focuses on:

  • iOS only
  • Swift packages only
  • common #Preview blocks
  • basic PreviewProvider support
  • persistent XcodeGen-generated host reuse

Requirements

  • macOS
  • Xcode / xcodebuild
  • Swift 6.2+
  • XcodeGen for first-time host generation

Install XcodeGen:

brew install xcodegen

Build

swift build

Usage

xcpv open <file>
xcpv watch <file>
xcpv run <file>
xcpv inspect <file>
xcpv clean

xcpv open <file>

  • resolves package / target / product
  • creates or reuses the host project
  • rewrites GeneratedPreviewHost.swift
  • opens the cached Xcode project

Example:

swift run xcpv open Sources/FeatureUI/ContentView.swift

xcpv watch <file>

Prepares the cached host project, boots an iOS Simulator, launches PreviewHostApp, and keeps it updated from the CLI.

Behavior:

  • selects and boots an iOS Simulator device
  • performs an initial build + install + launch of PreviewHostApp
  • watches the selected source file
  • regenerates only GeneratedPreviewHost.swift
  • when only the generated bridge changed, rebuilds PreviewContent.dylib directly with swiftc
  • otherwise rebuilds PreviewHostApp with watch-optimized xcodebuild flags
  • coalesces rapid edits by canceling an in-flight rebuild and restarting from the latest file state
  • skips simulator updates when the rebuilt app binary or dylib is unchanged
  • otherwise reinstalls or syncs the simulator app and relaunches PreviewHostApp
  • can optionally print per-phase timings, compiler incremental diagnostics, and use an experimental fast-install path
  • does not open Xcode
swift run xcpv watch Sources/FeatureUI/ContentView.swift

Useful watch flags:

  • --timings prints bridge/build/update/relaunch timings for each rebuild
  • --show-incremental prints the Xcode build timing summary plus any available Swift incremental compilation diagnostics
  • --fast-install uses an experimental simulator bundle sync path to avoid simctl install on rebuilds when possible

Example:

swift run xcpv watch --timings --show-incremental --fast-install Sources/FeatureUI/ContentView.swift

xcpv run <file>

Attempts to:

  • boot an iOS Simulator
  • build the cached host app
  • install and launch it

If that flow fails, xcpv falls back to opening the Xcode project.

swift run xcpv run Sources/FeatureUI/ContentView.swift

xcpv inspect <file>

Prints:

  • package root
  • target
  • product
  • transitive local target dependencies
  • detected previews
  • host project path
  • cache key
swift run xcpv inspect Sources/FeatureUI/ContentView.swift

xcpv clean

Removes the cache directory.

swift run xcpv clean

Cache layout

Cached hosts live under:

~/Library/Caches/xcpv/
  hosts/
    <hash>/
      project.yml
      PreviewHost.xcodeproj
      App/
        PreviewHostApp.swift
        GeneratedPreviewHost.swift
      metadata.json

Cache identity

The host cache key is derived from:

  • package root
  • selected library product
  • platform (iOS)

Reuse rules

The full Xcode project is regenerated only when:

  • the host project is missing,
  • metadata is missing or incompatible,
  • the host schema version changes.

The frequently-changing file is:

  • App/GeneratedPreviewHost.swift

That file is rewritten deterministically and only when content changes.

How it works

1. Package discovery

xcpv walks upward from the selected Swift file until it finds Package.swift.

2. SwiftPM introspection

It runs:

swift package dump-package

and decodes the manifest JSON to resolve:

  • package name
  • targets
  • products
  • local target dependencies

3. Target and product resolution

The tool determines which target owns the selected file, then chooses a direct library product containing that target.

If a target is only reachable transitively through another product, xcpv reports that clearly instead of guessing.

4. Preview parsing

swift-syntax is used to inspect the file and detect:

  • #Preview
  • PreviewProvider

For multiple previews, the generated host renders them in a TabView.

5. Host project generation

A cached XcodeGen spec produces a minimal iOS app target:

  • app target: PreviewHostApp
  • project name: PreviewHost
  • stable app entry source: PreviewHostApp.swift
  • generated bridge source: GeneratedPreviewHost.swift

The host app depends on the local Swift package and links the resolved library product.

6. Simulator refresh + watch coordination

At runtime, PreviewHostApp loads preview content from PreviewContent.dylib, which is compiled from GeneratedPreviewHost.swift.

During watch, xcpv chooses the fastest refresh path it can:

  • bridge-only edit: compile just PreviewContent.dylib with swiftc and sync it into the installed simulator app
  • library/source edit or failed fast path: fall back to a full xcodebuild and simulator app update

The watch loop debounces file changes, coalesces overlapping rebuild requests, and cancels superseded subprocesses so the latest edit wins.

Architecture

Sources/
  XcpvCLI/
    main.swift
    CLI/
      XcpvCommand.swift
      Commands.swift
    Core/
      Models/
      PackageDiscovery/
      SwiftPM/
      Parsing/
      Generation/
      Hosting/
      Watching/
      Support/

Key modules:

  • CLI: ArgumentParser commands
  • PackageDiscovery: Package.swift lookup
  • SwiftPM: dump-package loading, target/product resolution
  • Parsing: preview extraction with swift-syntax
  • Generation: deterministic bridge generation + file writing
  • Hosting: cache identity, XcodeGen spec, reusable host project, direct bridge dylib compilation, watch-optimized simulator build / install / relaunch, diagnostics, and experimental fast-install sync
  • Watching: debounced single-file watching plus rebuild coordination that coalesces changes and cancels superseded rebuilds
  • Support: logging, subprocess execution, path helpers, and cancellation primitives

Limitations

Current MVP limitations:

  • only iOS host generation is implemented
  • first-time host generation requires xcodegen in PATH
  • preview parsing is optimized for common #Preview { ... } forms
  • complex macro argument edge cases are not exhaustively handled yet
  • generated bridge code imports the resolved library product; previews that rely on non-exported/internal symbols may not compile from the host app module
  • PreviewProvider extraction supports the common static var previews: some View { ... } pattern best

Tips for large packages

xcpv resolves the watched file to its owning SwiftPM target and then builds the corresponding library product plus its transitive target dependencies.

If your preview file lives in a large target like MyLibraryCore, changing even a single preview string still pays for:

  • incremental recompilation inside that target
  • Swift module emission for that target
  • relinking the preview host app
  • simulator update / relaunch work

A practical way to reduce that cost is to move preview-only files into a tiny preview-support target that depends on the main library target.

Conceptually:

products: [
    .library(name: "MyLibraryCore", targets: ["MyLibraryCore"]),
    .library(name: "MyLibraryPreviewSupport", targets: ["MyLibraryPreviewSupport"])
],
targets: [
    .target(name: "MyLibraryCore", dependencies: ["MyLibraryInternal", "MyLibraryThemes"]),
    .target(name: "MyLibraryPreviewSupport", dependencies: ["MyLibraryCore"])
]

Then place preview-facing fixtures and preview wrapper views in MyLibraryPreviewSupport and point xcpv watch at files in that target. That keeps the watched build unit smaller than the main library target.

Tradeoffs:

  • the preview-support target can only use APIs visible across target boundaries (public or package as appropriate)
  • previews that rely heavily on internal implementation details may need small adapter APIs or helper types

Tests

Included tests cover:

  • package discovery
  • dump-package manifest decoding
  • target resolution
  • product selection
  • preview detection
  • bridge generation
  • cache reuse behavior
  • xcodebuild request generation
  • simulator prepare / launch sequencing and bridge dylib fast-path refreshes
  • process cancellation and watch rebuild coordination
  • file watcher change detection

Run them with:

swift test

License

MIT. See LICENSE.

Quick Setup
Installation guide for this server

Installation Command (package not published)

git clone https://github.com/hmSchuller/mcpv
Manual Installation: Please check the README for detailed setup instructions and any additional dependencies required.

Cursor configuration (mcp.json)

{ "mcpServers": { "hmschuller-mcpv": { "command": "git", "args": [ "clone", "https://github.com/hmSchuller/mcpv" ] } } }