№ 0297GitHub
pproxy for muse on OpenRouter
A translating proxy that lets the muse coding agent run on OpenRouter despite its compiled-out provider support; the included verifier drives the real muse binary and passes 19/19 checks.
pproxy
A translating proxy that lets the muse coding agent run on OpenRouter.
muse's own provider support for OpenRouter is compiled out of the shipped binary
(provider 'openrouter' is not compiled into this build), and its meta provider
speaks a proprietary dialect. This proxy sits between them: muse is pointed atpproxy with --base-url, and pproxy talks to OpenRouter.
Status: verified working end to end. uv run pproxy-verify drives the realmuse binary through the proxy and passes 19/19 checks.
Quick start
export OPENROUTER_API_KEY=sk-or-...
uv run pproxy # starts on 127.0.0.1:8817
# in another shell — META_API_KEY is an unused placeholder
MUSE_NO_AUTO_UPDATE=1 META_API_KEY=unused \
muse --provider meta --base-url http://127.0.0.1:8817 \
--model anthropic/claude-opus-5 --yolo
What it translates
| muse sends | pproxy does | upstream |
|---|---|---|
GET /muse-code/models |
rewrite schema | GET /models |
POST /responses |
swap credential, backfill sequence_number |
POST /responses |
Two findings drove the design, both established by experiment rather than assumed:
The catalog is proprietary.
/muse-code/modelsis muse-specific in both path
and schema. Rows needid,model_id,provider_id,profile_id,display_label,visibility,release_date,display_order,is_default,context_limit,output_limit; exactly one row must beis_defaultand visible;
ids must be unique.provider_idstays"meta"on every row — muse rejects rows
whose provider disagrees with the selected provider. The OpenRouter slug rides inid/model_id.muse requires
sequence_numberon every SSE event. It reports onlyerror_kind=decodewith no field name.pproxy-schemaprobebisected it: a stream
identical except for that field is rejected, and accepted with it. OpenRouter does
not always emit it, so the proxy backfills. The request body needs no translation
at all — muse speaks the Responses API and OpenRouter serves/responses.
Credentials
muse only ever sends Bearer $META_API_KEY and has no concept of an OpenRouter key,
so the pro





