npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

swizzler-mcp

v0.1.2

Published

Read your Swizzler cocktail library from Claude, Codex, and other MCP clients

Readme

swizzler-mcp

An MCP server that lets an AI assistant read your Swizzler cocktail library — search recipes, pull up a spec, work out what you can make from the bottles on your shelf, and look at what you've actually been drinking. Works with Claude, Codex, and other MCP-compatible clients.

Read-only. Nothing here can change your library.

The iOS app is closed source; this server is not. It is the piece that runs on your own Mac and touches your recipe data, so it is the piece worth being able to read.

How it works

Swizzler stores recipes on-device in SwiftData, synced through your private CloudKit database. Neither of those is reachable from a desktop MCP server, so the app publishes a snapshot instead: turn on Settings → AI Assistants → Share Library, and Swizzler writes a photo-free copy of your library to its own iCloud Drive folder. This server reads that file from your Mac.

iPhone/iPad ──SwiftData──> private CloudKit  (app's own sync, untouched)
     │
     └──snapshot──> iCloud Drive/Swizzler/Library.swizzle ──> swizzler-mcp ──> Claude

Freshness

The snapshot only refreshes while Swizzler is running — it rewrites on every edit and when the app goes to the background. In practice that covers the single-device case completely, because your library can only change while the app is open in front of you.

Where it can lag is multi-device: edit on your iPad, then ask Claude on your Mac without opening Swizzler on any device that has synced. So every tool result states the snapshot's age, and past 24 hours it says so with a warning rather than answering as if the data were current. Ask Claude to check snapshot_status any time you want to know.

Install

One command, the same for every client. It runs straight from npm — nothing to download, build, or keep up to date.

Claude Code

claude mcp add swizzler -- npx -y swizzler-mcp

Codex

codex mcp add swizzler -- npx -y swizzler-mcp

Claude Desktop — add this to claude_desktop_config.json:

{
  "mcpServers": {
    "swizzler": {
      "command": "npx",
      "args": ["-y", "swizzler-mcp"]
    }
  }
}

Anything else that speaks MCP — run npx -y swizzler-mcp over stdio.

Node 20 or newer is the only requirement, and npx ships with it.

From a clone

git clone https://github.com/chrisscott/swizzler-mcp.git
cd swizzler-mcp
npm install
npm run build
claude mcp add swizzler -- node "$PWD/dist/index.js"

By default it reads:

~/Library/Mobile Documents/iCloud~com~getswizzler~app/Documents/Library.swizzle

Set SWIZZLER_LIBRARY_PATH to point somewhere else.

Tools

| Tool | What it answers | |---|---| | snapshot_status | How current is this data, and where did it come from? | | diagnose_sync | Why are recipes missing or stale? Checks iCloud Drive on this Mac. | | search_recipes | By name, ingredient, spirit, collection, or favourites | | get_recipe | The full spec for one drink | | whats_next | The Next Round queue — what you've lined up to make | | list_collections | Your collections and their sizes | | what_can_i_make | Given these bottles, what's within reach (and what's missing)? | | recipe_history | What you've actually made, how often, and how you rated it |

Smart collections

Smart collections have no stored membership — the app evaluates their rules at query time. The snapshot resolves them into concrete memberships before writing, so the rule engine stays in Swift rather than being reimplemented here and drifting. Backup exports keep them as rules, so re-importing restores a smart collection rather than freezing today's matches.

Tests

npm test

Drives the built server over stdio with a real MCP client against fixture libraries, covering search, detail rendering, staleness warnings, and the missing-snapshot path.

Releasing

On a v* tag, .github/workflows/release.yml runs the suite, creates a GitHub release, and publishes to npm. npm is the only distribution channel — there is no download.

# bump the version in package.json first — the workflow fails the build if it
# disagrees with the tag
git tag v0.2.0 && git push --tags

npm publishing uses OIDC trusted publishing, so there is no token in the repo. It needs one-time setup on npmjs.com under the package's Settings → Trusted Publisher: repository chrisscott/swizzler-mcp, workflow release.yml. That can only be configured for a package that already exists, so the very first publish has to be done by hand.

A version already on the registry is skipped rather than failing the run, so re-running a release is safe.

workflow_dispatch runs the same build and tests without publishing, which is the way to check the pipeline before tagging.

Troubleshooting

"No Swizzler library snapshot at …" — Check three things, in this order:

  1. iCloud Drive is on for this Mac. System Settings → your name → iCloud → iCloud Drive. If it is off, nothing syncs down at all and ~/Library/Mobile Documents/ will hold only an empty com~apple~CloudDocs. To check from a terminal:

    defaults read MobileMeAccounts | grep -A2 MOBILE_DOCUMENTS

    Enabled = 0 means iCloud Drive is off.

  2. Sharing is on in the app. Settings → AI Assistants → Share Library. The status row underneath reports what the last write actually did.

  3. The snapshot has been published since you turned it on. Background the app to force a write, then give iCloud a minute.

The Swizzler folder doesn't appear in Finder — iOS caches the NSUbiquitousContainers key, so the folder sometimes only shows up after the app's build number changes.

Recipes look out of date — Open Swizzler on the device you last edited on. The snapshot is republished when the app backgrounds.