Skip to main content

hapbeat-helper

Local daemon that bridges Hapbeat Studio (Web SPA at https://devtools.hapbeat.com) to Hapbeat hardware on the local network.

The browser cannot do mDNS, UDP broadcast, or raw TCP sockets directly. hapbeat-helper runs in the background, exposes a WebSocket on ws://localhost:7703, and relays Studio requests to the devices using UDP (port 7700) and TCP (port 7701).

Studio (https://devtools.hapbeat.com)
        │  ws://localhost:7703 (JSON)
        ▼
hapbeat-helper (this daemon)
        │  UDP 7700 (PLAY / STOP / PING / streaming)
        │  TCP 7701 (config / kit deploy)
        │  mDNS (_hapbeat._udp.local.)
        ▼
   Hapbeat devices

Install

hapbeat-helper is distributed as a Python CLI that runs in its own isolated environment. The recommended installer is pipx — it puts each Python tool in a separate venv and exposes the entry point on your PATH, so you don't need to think about Python versions or dependency conflicts.

Step 1 — Install pipx (once per machine)

macOS

brew install pipx
pipx ensurepath

Windows

py -m pip install --user pipx
py -m pipx ensurepath
# Close and reopen your terminal so the new PATH takes effect.
pipx --version    # should print the version

Windows tip: if pipx is still "not recognized" after reopening the shell, use py -m pipx ... for everything below (it works identically). The bare pipx command becomes available once %APPDATA%\Python\Python3xx\Scripts is on your Path.

OneDrive / cloud-synced home directory: if your C:\Users\<you>\ is synced by OneDrive, pipx may fail with WinError 448 — untrusted mount point. Move pipx out of the synced tree by setting these environment variables (User scope) and reopening the shell:

[Environment]::SetEnvironmentVariable('PIPX_HOME',    'C:\pipx\home', 'User')
[Environment]::SetEnvironmentVariable('PIPX_BIN_DIR', 'C:\pipx\bin',  'User')

Step 2 — Install hapbeat-helper

Once pipx is on your PATH:

pipx install hapbeat-helper

That's it. hapbeat-helper will be available in any new terminal.

Local development (from a clone of this repo)

# editable install via pipx (changes in src/ are picked up live)
pipx install -e .

# or — preferred during active dev — a plain venv:
python -m venv .venv
# macOS:
.venv/bin/pip install -e ".[dev]"
.venv/bin/hapbeat-helper start
# Windows:
.venv\Scripts\pip install -e ".[dev]"
.venv\Scripts\hapbeat-helper start

Updating

pipx upgrade hapbeat-helper

If you installed editable from a clone (pipx install -e . or pip install -e ".[dev]"), updates are automatic — just git pull and restart the daemon. The Python package picks up changes in src/ on the next process start.

WS protocol mismatch? When Studio reports ERROR: unknown type: <message> in the log drawer, your helper is older than the Studio build. git pull && restart (or pipx upgrade).

Update notices

When a newer release exists on PyPI, hapbeat-helper start prints a single line about it, and hapbeat-helper version always reports it. It is one scrolling line with nothing to dismiss, so it simply prints on every start rather than being suppressed after the first sighting.

The lookup reads a static release feed (https://devtools.hapbeat.com/releases.json), times out after 3 seconds and stays completely silent on failure, so it is a no-op on isolated networks. Disable it with --no-update-check or HAPBEAT_NO_UPDATE_CHECK=1.

Uninstalling

pipx uninstall hapbeat-helper

Run

Register hapbeat-helper as an OS-level service so it starts automatically every time you log in. After this one-time setup you never need to open a terminal again:

hapbeat-helper install-service

To check the registration state:

hapbeat-helper service-status

To remove the auto-start registration:

hapbeat-helper uninstall-service

Platform notes:

  • macOS — creates ~/Library/LaunchAgents/com.hapbeat.helper.plist (launchd)
  • Windows — drops a hidden VBS shim into the Startup folder (%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\hapbeat-helper.vbs) that launches the daemon at login with no console window. stdout/stderr → %LOCALAPPDATA%\hapbeat-helper\hapbeat-helper.log

Option B — Foreground (dev / debug)

hapbeat-helper start

Then open https://devtools.hapbeat.com — Studio will connect automatically.

Press Ctrl+C to stop.

Other commands

hapbeat-helper status      # check whether a daemon is reachable on 7703
hapbeat-helper version     # print version (and any newer release)
hapbeat-helper config show # show config path

Firmware OTA from the CLI

Push a firmware app image to one device over Wi-Fi, without opening Studio:

hapbeat-helper ota 192.168.0.48 dist/necklace_v3/firmware_app_ota.bin
hapbeat-helper ota duo-01 dist/necklace_v3/firmware_app_ota.bin   # by device name

The target is an IP address or a device name; names are resolved through the running daemon, so an IP is required when no daemon is up. Pass the app-only image (firmware_app_ota.bin) — a merged serial image is rejected before anything is sent. Exit code is 0 on success, 1 on OTA failure, 2 on a bad argument or an unresolvable target.

AI agent integration (MCP)

hapbeat-helper mcp is a local MCP server (stdio) that lets an AI agent on your PC — Claude Code, Codex — drive Studio's AI trials directly: read the guide and knowledge base, submit a trial, open it for you to try, and wait for your rating. It is a thin relay: every tool call goes through the running daemon to the Studio tab, and Studio does the work (validation, rendering, knowledge-base writes). Only you rate candidates; the agent never writes ratings. File-based exchange (inbox/) keeps working.

Claude Code / Codex ──stdio──▶ hapbeat-helper mcp
                                  │ ws://127.0.0.1:7703
                                  ▼
                            hapbeat-helper daemon ──relay──▶ Studio tab (Waveform editor, folder open)

Install

The MCP SDK is an optional extra:

pipx install --force "hapbeat-helper[mcp]"
# from a clone of this repo:
pipx install --force --editable ".[mcp]"

Without the extra, hapbeat-helper mcp prints these commands and exits with code 2.

Register with your agent

Claude Code:

claude mcp add hapbeat -s user -- hapbeat-helper mcp

Codex — add to ~/.codex/config.toml:

[mcp_servers.hapbeat]
command = "hapbeat-helper"
args = ["mcp"]

Add --port N to the args if your daemon is not on 7703.

Prerequisites while using it

  1. The daemon is running (hapbeat-helper start or install-service).
  2. Hapbeat Studio is open with the Waveform editor showing a folder. That tab registers itself as the agent endpoint; if several tabs qualify, the one that registered last receives the requests.

Otherwise tools fail with HELPER_NOT_RUNNING: ... (no daemon) or STUDIO_NOT_READY: ... (no Studio tab ready). Requests time out after 30 s (submit_trial: 120 s) with TIMEOUT: ....

Tools

Tool Arguments Purpose
status — Studio version, open folder, clip / trial / unrated counts, dimensions
get_guide — Agent guide (read first): trial format and workflow
get_catalog — Existing clips in the folder
get_knowledge term? Term index + dimensions + insights, or one term's document
submit_trial trial (hapbeat-trial@1 object) Validate, render and store a trial; returns trialId and per-candidate features
get_trial trialId Request, candidates and rating (null while unrated)
list_trials limit? (1–100, default 20), unratedOnly? Recent trials
audition trialId, candidateId, play? Open the trial in the editor's AI-trials tab; play: true also starts playback
adopt trialId, candidateId Adopt a candidate as a clip (same as the Adopt button)
propose_insight statement (≤ 1000 chars), evidence (1–20 × trialId/candidateId) Append to the Proposed section of insights.md
wait_for_rating trialId, timeoutSec? (10–1800, default 300) Poll every 2 s; {status: "rated", rating} or {status: "waiting"} (call again)

Relay messages

Same {"type": ..., "payload": {...}} envelope as the rest of the WS API. These messages are routed only between the MCP client and the endpoint tab — never broadcast, never passed to the device handlers.

type Direction payload Helper behaviour
agent_endpoint_register Studio → helper { studioVersion, folderName } Make the sender the agent endpoint (last wins); reply agent_endpoint_registered {}
agent_endpoint_unregister Studio → helper {} Clear the endpoint if the sender is it
agent_request MCP → helper → Studio { requestId, method, params } Forward unchanged to the endpoint and remember the requester. No endpoint → agent_response { requestId, ok: false, error: "STUDIO_NOT_READY: ..." }
agent_response Studio → helper → MCP { requestId, ok, result?, error? } Forward to the requester and forget the request. Accepted only from the tab the request went to; dropped if the requester is gone
  • Endpoint disconnects → every request still pending on it is answered with ok: false, error: "STUDIO_DISCONNECTED". Requester disconnects → its pending requests are dropped.
  • requestId must match ^[A-Za-z0-9_-]{1,64}$ (otherwise an error message is returned and nothing is forwarded). A duplicate pending id is answered with DUPLICATE_REQUEST_ID; a payload over 4 MB (JSON, UTF-8) with PAYLOAD_TOO_LARGE.

素材台帳(materials)

Free sound-effect sites get downloaded from in bulk, and a month later nobody remembers where a file came from. The material ledger records it at download time — site, source page, license — and ties it to the SHA-256 of the file content, so renaming or moving a file never loses it. Studio registers the files it exports from those originals, and a Kit's CREDITS.md is generated from the ledger.

Commands

hapbeat-helper materials ingest --dry-run      # what would be taken from ~/Downloads
hapbeat-helper materials ingest                # copy new audio / zip downloads into the ledger
hapbeat-helper materials ingest --dir D:\sfx --since 90
hapbeat-helper materials list --needs-review   # materials whose license is unknown
hapbeat-helper materials list --site maou.audio
hapbeat-helper materials show path\to\gunshot.wav   # or a sha256
hapbeat-helper materials set-license --site otologic.jp --license-id CC-BY-4.0 \
    --name "OtoLogic (CC BY 4.0)" --url https://otologic.jp/free/license.html \
    --credit OtoLogic --verified
hapbeat-helper materials set-license --sha <sha256> --license-id CC0-1.0
hapbeat-helper materials credits MyKit/        # CREDITS.md to stdout
hapbeat-helper materials where                 # print the materials dir
  • ingest scans the top level of the folder (default ~/Downloads) for .wav .mp3 .ogg .flac .m4a .aif .aiff .opus and .zip (audio members are extracted). Files are copied; the downloads stay where they are. Content already in the ledger is reported as a duplicate and skipped. --since DAYS defaults to "since the last ingest" (30 days on the first run).
  • The source is read from the Windows download mark (Zone.Identifier: ReferrerUrl / HostUrl). Without it (other OS, file not from a browser) the site is _unknown.
  • set-license --site edits sites.json; --sha appends a per-file override. --attribution / --no-attribution defaults to yes for CC-BY* ids.

Materials dir

Default ~/HapbeatMaterials/; change it with materials_dir in the config file (hapbeat-helper config show prints its path):

materials_dir = "D:/HapbeatMaterials"
materials_watch_downloads = false   # true: the daemon ingests new downloads by itself
HapbeatMaterials/
  store/<site>/<YYYY-MM>/<name>   read-only copy of each original (name collisions get " (2)")
  ledger.jsonl                    append-only records: hapbeat-material@1 / hapbeat-derived@1 / hapbeat-license-override@1
  sites.json                      domain → license rules (yours to edit; seeded on first use)
  MATERIALS.md                    overview by site and month, regenerated on every change
  state.json                      internal (last ingest time)

Licenses are resolved on every lookup — per-file override, then the site rule in sites.json (a perAsset site such as freesound.org resolves to unknown and needs review), then unknown — so fixing a rule later applies to every material already ingested. CREDITS.md in a Kit is described in hapbeat-contracts specs/kit-format.md.

With materials_watch_downloads = true the daemon polls ~/Downloads every 10 s and ingests a new file once its size is unchanged across two polls (download finished). Off by default.

WS messages

Answered to the sender only; requestId in the payload is echoed back when present. Invalid payloads get the same reply type with an error string.

type payload reply
material_lookup { requestId?, sha256s: string[] (≤ 500) } material_lookup_result { requestId?, results: { <sha>: { kind: "material" | "derived" | "unknown", originals: [{ sha256, site, referrerUrl, hostUrl, originalName, storePath, license, needsReview }] } } }
material_register_derived { requestId?, sha256, parents: string[] (1–64), tool, name?, note? } material_register_derived_result { requestId?, ok } — an identical sha256 + parents record is not appended twice
material_credits { requestId?, sha256s: string[] (≤ 500), toolName } material_credits_result { requestId?, markdown }

A derived file resolves to the originals reached through its parents (cycles and chains deeper than 32 are cut).

Verify

Quick smoke test using websocat:

echo '{"type":"ping","payload":{}}' | websocat ws://localhost:7703
echo '{"type":"list_devices","payload":{}}' | websocat ws://localhost:7703

Troubleshooting

  • Studio reports "Helper 未接続" — run hapbeat-helper install-service (once) or start manually with hapbeat-helper start.

  • Browser cannot connect to ws://localhost:7703 from HTTPS Studio — Chrome and Edge allow this by default. Firefox requires network.websocket.allowInsecureFromHTTPS = true in about:config.

  • No devices found — confirm the Hapbeat devices and this PC are on the same Wi-Fi network. Some hotspot/AP modes block UDP broadcast and mDNS.

  • Port 7700 / 7703 already in use — stop any running hapbeat-manager (it owns the same ports). The two cannot run at the same time.

  • Windows: pipx install fails with WinError 448 — untrusted mount point — your home directory is under OneDrive (or another reparse point). pipx finished installing the package but cannot finalize the shim under ~/.local/bin/. Either run hapbeat-helper.exe from that path directly, or relocate pipx outside the synced tree:

    [Environment]::SetEnvironmentVariable('PIPX_HOME',    'C:\pipx\home', 'User')
    [Environment]::SetEnvironmentVariable('PIPX_BIN_DIR', 'C:\pipx\bin',  'User')
    # Reopen the shell, then:
    py -m pipx ensurepath
    py -m pipx install hapbeat-helper
    
  • pipx not recognized after pip install --user pipx — the user Scripts dir is not on Path yet. Run py -m pipx ensurepath and open a new terminal. As a fallback, every pipx X call also works as py -m pipx X.

ドキュメント

公式ドキュメントは https://devtools.hapbeat.com/docs/helper/ を参照してください。 インストール手順 / CLI リファレンス / セキュリティ解説などをまとめています。

License

MIT

Metadata

Release files for hapbeat-helper 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hapbeat-helper 0.5.0
File Size Uploaded Provenance
hapbeat_helper-0.5.0.tar.gz 138.9 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for hapbeat-helper 0.5.0
File Interpreter ABI Platform
hapbeat_helper-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 253.2 kB

Release files / hapbeat_helper-0.5.0.tar.gz

Download URL hapbeat_helper-0.5.0.tar.gz
Size 138.9 kB
Tags Source
SHA-256 checksum
How to use checksums
662bee2b59db1e8ca7a4393a50e16c2853a5e840e32565f59ee47c99014f0421
BLAKE2b-256 checksum
How to use checksums
71c2bd7711358a803ff14a790c6d30da5283e23c4b1e1a010a52d267f20f3a10
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / hapbeat_helper-0.5.0-py3-none-any.whl

Download URL hapbeat_helper-0.5.0-py3-none-any.whl
Size 114.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f4c98122804dd7c01c8d89074d7aa32b2ef3db8c27c2a09cd041bcb5341f54c8
BLAKE2b-256 checksum
How to use checksums
90ef4117b3b77c1eb11444a418f8674fce98a220e653bf887644e852c829477e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Security for hapbeat-helper 0.5.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for hapbeat_helper-0.5.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page