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

puffco-mcp

v0.4.0

Published

MCP server to control a Puffco New Proxy / Peak Pro over Bluetooth LE (LORAX protocol)

Readme

An MCP server to control Puffco Devices over Bluetooth LE.

Exposes the device as MCP tools (connect, status, preheat, boost, profiles, temperature, stealth, lantern, colors, brightness) so any MCP client can drive your Puffco.

Protocol credit: Fr0st3h/Puffco-Reverse-Engineering-Writeup. Reverse-engineered for personal interoperability. Not affiliated with Puffco.

Requirements

  • Node.js 20+
  • A machine with Bluetooth LE, within ~10m of the device
  • The Puffco in Bluetooth/pairing range (not connected to the phone app)

macOS uses CoreBluetooth via @stoprocent/noble — grant the terminal/host Bluetooth permission on first run.

Install & run

No install needed — run straight from npm with npx:

npx puffco-mcp

Or install globally:

npm install -g puffco-mcp
puffco-mcp

MCP client config (npx)

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

OpenClaw

openclaw mcp add puffco --command npx --arg -y --arg puffco-mcp

From source

npm install
npm run build
node dist/index.js

Tools

| Tool | Description | |------|-------------| | puffco_connect | Scan, connect, run LORAX auth handshake | | puffco_disconnect | Disconnect | | puffco_status | Battery %, heater temp, operating state, total dabs, name | | puffco_device_info | Model, serial, firmware revision | | puffco_diagnostics | Full telemetry: heater power/duty/resistance/voltage/current, battery voltage/temp/capacity/current, charge/input current, magnetic field, uptime, safety thermal est, raw heater temp | | puffco_stats | Lifetime/trip heat cycles + time, total dabs, dabs/day, approx dabs remaining, chamber type | | puffco_profile_get | Read one or all 4 heat profiles (name, temp, time, color, boost) | | puffco_profile_set | Set one profile field (name/temp/time/color/boostTemp/boostTime) | | puffco_logs | Read audit + fault logs (best-effort) | | puffco_set_brightness | Set LED brightness 0-255 (all segments) | | puffco_preheat | Start a heat cycle | | puffco_abort | Abort/stop the current heat cycle | | puffco_boost | Boost active cycle | | puffco_command | Raw device command (heatCycleStart/Abort/Boost, sleep, idle, …) | | puffco_select_profile | Select profile 1-4 | | puffco_set_temp | Override cycle temperature (C) | | puffco_stealth | Toggle stealth mode | | puffco_lantern | Lantern on/off | | puffco_lantern_color | Lantern RGB | | puffco_dabs_today | Dabs today (cloud) + avg duration & popular temp | | puffco_dab_history | Dab history by period (d/w/m/y/all) — cloud account API | | puffco_last_dab | Timestamp of the most recent dab (cloud) |

Cloud metrics (dab history)

The BLE/LORAX interface exposes only lifetime odometer counters — the device has no real-time clock and no per-dab timestamps. The Puffco app's Metrics tab (dabs today/week/month, average duration, popular temp) comes from the account cloud API (api.puffco.app). The puffco_dabs_today / puffco_dab_history / puffco_last_dab tools mirror that API so you get app-accurate, date-ranged numbers.

These tools authenticate as your own Puffco account — no credentials are bundled with the package. Provide tokens one of two ways:

  1. Env var (simplest): set PUFFCO_REFRESH_TOKEN to your account's refresh token (from the app/web localStorage.refreshToken). The server auto-refreshes the short-lived access token from it and persists the rotated pair.
  2. Extract helper: run a Chrome with remote debugging on a logged-in puffco.app tab, then:
    node scripts/extract-tokens.mjs --port 9222
    This writes ~/.config/puffco-mcp/tokens.json (override with PUFFCO_TOKEN_FILE).

Optional env: PUFFCO_SERIAL (default device for puffco_last_dab), PUFFCO_TIMEZONE (default America/New_York).

⚠️ This calls a private, undocumented Puffco endpoint with your personal account auth. It's for your own use — don't share or publish your tokens.

Full token walkthrough: see SETUP.md.

For AI agents

If you're an MCP/agent client, see SKILL.md for a task-oriented guide: when to use BLE vs cloud tools, the connect-first rule, the heating safety rule, and how to answer "how many dabs today?". SKILL.md is OpenClaw-skill compatible (frontmatter + MCP install metadata).

How it works

The New Proxy does not use the Peak Pro one-characteristic-per-field GATT. It speaks the LORAX protocol — a path-based command/reply system over service e276967f-…:

  • 60133d5c (write) — command channel; 8dc5ec05 / 43312cd1 (notify) — replies/events
  • Frame: seqId(u16le) + opcode(u8) + payload; replies matched by seqId
  • Opcodes: getAccessSeed(0), unlock(1), getLimits(2), readShort(16), writeShort(17), write(34)
  • Values addressed by path, e.g. /p/bat/soc, /p/app/mc, /p/app/stat/id
  • Auth: getAccessSeed → SHA256(HANDSHAKE2 ‖ seed)[:16] → unlock
  • Battery SOC is a u16 fixed-point hundredths (9471 = 94.71%)

The legacy Peak Pro f9a98c15-… layout (Firmware X E0 handshake) is also mapped in src/protocol.ts.

Protocol credit: meekzyr/PuffcoPC and Fr0st3h.

Status

v0.4 — New Proxy (LORAX) device control + telemetry (live-verified reads, auth, and write/heat path), full per-profile editing, and cloud dab-history tools (dabs today/week/month, app-accurate). Audit-log readout is best-effort. PRs welcome.

License

MIT