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

@miadi/voice-mcp

v0.4.3

Published

MCP server fronting the Miadi voice layer with episode addressing — play, find, publish and mint episode-bound voice from an agent's tool surface.

Readme

@miadi/voice-mcp

An MCP server that lets an agent play, find and publish voice messages tied to Miadi episodes, and create an episode when none fits.

In the Miadi stack, this is how an agent uses voice from its own tool loop. It is a front over @miadi/voice-client, so the audio, the ledger and the credentials stay on the Miadi server, and it reads episode folders from the chronicle. All six tools work.

Tools

| Tool | Purpose | State | |---|---|---| | voice_publish_to_episode | Produce audio bound to its episode from the moment it exists | works | | voice_play_episode | Resolve an episode to its voice audio and return playable references | works | | voice_list_episode_voices | Enumerate and search an episode's voices | works | | voice_resolve_episode | Answer which episode an agent is inside — with the reason, the alternatives, and an honest null | works, from what it is given | | voice_create_episode | Mint a vessel when none fits, reporting all five closing stages | works (0.4.0) | | voice_episode_closing_status | Re-prove the five closing stages, read-only, naming drift | works (0.4.0) |

Publishing requires a return address

voice_publish_to_episode takes a required origin. A voice nobody can be steered back through cannot be answered, and that — not the audio — is what the portal card is for.

"origin": {
  "user":        "mia",              // whoami
  "host":        "my-host",          // hostname -s, not the FQDN
  "cwd":         "/home/me/project", // pwd
  "multiplexer": "tmux",             // or "herdr". "none" is refused.
  "session":     "work",             // tmux display-message -p "#{session_name}"
  "pane":        "%127"              // $TMUX_PANE — herdr also needs workspace
}

Read these values — do not compose them. Inside herdr they are already in your environment and cost nothing:

| field | where it actually is | |---|---| | workspace | $HERDR_WORKSPACE_ID | | tab | $HERDR_TAB_ID | | pane | $HERDR_PANE_ID | | session | default when $HERDR_SOCKET_PATH is ~/.config/herdr/herdr.sock, else the <name> in .../herdr/sessions/<name>/herdr.sock |

Inside tmux: $TMUX_PANE and tmux display-message -p "#{session_name}". Read them in the same invocation that publishes — a pane id copied from another message is a real id pointing at somebody else's terminal.

The server is the authority, twice over:

  1. Shape. An absent, incomplete, or "none" declaration answers 400 { error, problems, help } — every missing field at once, plus the shape to send — and no TTS is spent on it.
  2. Truth. When the declaration names the portal's own host and user, it is probed against the live multiplexer inventory. An address that is not in it is refused, and the refusal prints what the inventory does hold, so an agent cannot invent a pane id that leads nowhere.

A probe that cannot run — another host, no herdr installed — is unprovable, not a refusal: it publishes, attested stays "self-declared", and the reason is recorded on the record. An unreadable inventory proves nothing in either direction.

reach is the server's verdict, never the caller's claim: declaring a different host or a multiplexer owned by another user publishes fine and renders as unreachable, because that is a fact about the topology rather than a defect in the declaration. attested: "server" means the pane was seen, not that this persona occupies it — the card says pane live rather than verified, and verified stays unspent until occupancy itself can be proven.

Resolution consults exactly what it is handed: an explicit reference, a caller-supplied cwd, or an existing record's binding. It does not rank those against a session origin or search the wheel. When nothing given answers, the tool says so; episode: null with a reason is a valid answer.

Architecture

A front, not a second implementation.

  • Audio bytes, the KV ledger and the Edge-TTS producer stay behind the Miadi server, which holds the KV credentials. This process reaches them through @miadi/voice-client, which owns the wire envelope and the token tier — so the HTTP surface is described once, not once per caller.
  • Episode folders are read from the chronicle root; the chronicle's medicine wheel is read at MIADI_CHRONICLE_MW_URL.
  • VoiceMessage keeps exactly one definition in this workspace: @miadi/voice's.
  • The only wheel write in the whole surface is the registration mkepisode performs during voice_create_episode. This server never POSTs or PUTs to the wheel itself.

Configuration

| Variable | Default | Meaning | |---|---|---| | MIADI_API_URL | http://127.0.0.1:3335 | Miadi server holding the voice routes | | MIADI_API_TOKEN_WRITER | — | Read and write. Required to publish. | | MIADI_API_TOKEN_READER | — | Read only; every publish answers 401 | | MIADI_CHRONICLE_MW_URL | http://127.0.0.1:8040 | Chronicle wheel. Read first; MW_API_URL_OVERRIDE / MW_API_URL are legacy fallbacks. | | MIADI_CHRONICLE_ROOT | /srv/miadi/episodes/miadi-chronicle | Episode folders | | MIADI_CHRONICLE_GIT_ROOT | /srv/miadi/episodes | Git root — one level above the chronicle root | | MIADI_MKEPISODE_PATH | …/mightyeagle/packages/passages/js/mkepisode.js | Vessel creation |

The chronicle wheel is the only correct target for episode work. A retired wheel host is refused outright, because an episode registered there would be lost.

MIADI_CHRONICLE_GIT_ROOT is a separate value rather than a derived one because a git -C pointed at the chronicle root reports a clean tree for a chronicle it cannot see.

Creating episodes: created is not closed

voice_create_episode performs stages 1 and 4 of the five-stage gate and returns every stage with its proof:

| Stage | Performed by | |---|---| | created | the tool | | committed | the human — the tool emits the exact git add of named files | | pushed | the human | | registered | the tool | | receipt-verified | the tool |

mkepisode exits 0 whether registration succeeded, skipped, or failed — registration is fail-open by design, so the gate belongs to the caller. The tool never runs git add, commit or push, never reports a later word than it proved, and reports unperformed stages as owed, which is a state, not an omission.

Server version

The episode binding is written by the server's publish route. A Miadi server built before that route accepted episode ignores the field and stores an unbound record, so check the running build before reading a missing binding as a client bug.