Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

Muse Code — Custom Provider & No Meta Login

Use Muse Code (muse) with any OpenAI-compatible API without creating a Meta account or using muse login.

Muse Code's meta provider defaults to https://api.meta.ai/v1, but you can override it with --base-url. The meta label is just a provider name — storing a key with muse auth set --provider meta does not require a Meta OAuth login. muse login is optional and only for Meta's hosted auth; API-key auth is enough.

Why

  • Route Muse Spark (muse-spark-1.2, etc.) through a gateway/proxy (e.g., self-hosted, OpenCode, Helicone, Cloudflare AI Gateway, LiteLLM)
  • Avoid muse login / browser OAuth entirely
  • Keep the same CLI (muse exec, muse TUI) while swapping the backend

Quick start (no Meta account)

1. Install Muse Code

curl -fsSL https://dev.meta.ai/install.sh | sh
muse --version  # Muse Code 0.2.1

2. Store an API key (no browser)

This does NOT create a Meta account. It just saves a key under the meta provider name.

# paste your gateway/proxy API key on stdin (never as an argv)
echo -n "YOUR_GATEWAY_API_KEY" | muse auth set --provider meta --api-key-stdin

# verify
cat ~/.config/muse/auth.json  # { "schema_version": 1, "providers": { "meta": { "api_key": "..." } } }

# alternative: env var (takes priority over file)
export META_API_KEY="YOUR_GATEWAY_API_KEY"

You never need to run muse login.

3. Run with a custom endpoint

Muse Code accepts --base-url per invocation. Pass your OpenAI-compatible base URL:

# headless (CI / scripts)
muse exec --base-url https://your-gateway.example.com/v1 "say hi in 5 words"

# with image (Muse Spark supports image/pdf/video -> text)
muse exec --base-url https://your-gateway.example.com/v1 --image ./photo.jpg "describe this image"

# interactive TUI with custom endpoint
muse --base-url https://your-gateway.example.com/v1 "fix the tests in this repo"

Model defaults to muse-spark-1.2 (~/.config/muse/settings.json{"schema_version":1,"model":"muse-spark-1.2","provider":"meta"}). Override per run:

muse exec --base-url https://your-gateway.example.com/v1 --model muse-spark-1.2 "task"

4. Make it permanent (wrapper)

To avoid typing --base-url every time, wrap the binary:

BIN="$HOME/.local/bin/muse-bin-0.2.1-R1215.1"  # or wherever `muse` is installed
BASE="https://your-gateway.example.com/v1"

cat > ~/.local/bin/muse-wrapper << SH
#!/bin/bash
BIN="$BIN"
BASE="$BASE"
case "\$1" in
  exec|resume|config|export|trace|skills|sandbox|session-message|auth|login|logout|init)
    exec "\$BIN" "\$1" --base-url "\$BASE" "\${@:2}"
    ;;
  *)
    exec "\$BIN" --base-url "\$BASE" "\$@"
    ;;
esac
SH
chmod +x ~/.local/bin/muse-wrapper
ln -sf ~/.local/bin/muse-wrapper ~/.local/bin/muse

# now just
muse exec "hello"
muse --image ./pic.png exec "what's in this image?"

Note on exec ordering: muse exec expects options after exec (muse exec --base-url ...), not before. The wrapper above handles this.

5. Keep the proxy alive (macOS)

If your custom provider is a local proxy (e.g., translating APIs), run it as a LaunchAgent:

<!-- ~/Library/LaunchAgents/com.muse-proxy.plist -->
<dict>
  <key>Label</key><string>com.muse-proxy</string>
  <key>ProgramArguments</key><array><string>/usr/bin/python3</string><string>/Users/you/.local/bin/my-muse-proxy.py</string></array>
  <key>RunAtLoad</key><true/>
  <key>KeepAlive</key><true/>
</dict>
launchctl load ~/Library/LaunchAgents/com.muse-proxy.plist
curl -s http://127.0.0.1:8914/v1/models | head

6. Minimal proxy example (Python)

Forward Muse's POST /responses to your gateway. Rewrite model names if needed:

import http.server, urllib.request, json
UPSTREAM = "https://your-gateway.example.com/v1"
API_KEY  = "YOUR_GATEWAY_API_KEY"  # read from env/keychain, don't hardcode

class H(http.server.BaseHTTPRequestHandler):
    def do_GET(self):
        if "models" in self.path:
            body = json.dumps({"object":"list","data":[{"id":"muse-spark-1.2","object":"model"}]}).encode()
            self.send_response(200); self.send_header("Content-Type","application/json")
            self.send_header("Content-Length", str(len(body))); self.end_headers(); self.wfile.write(body); return
        self.send_response(404); self.end_headers()
    def do_POST(self):
        body = self.rfile.read(int(self.headers.get("Content-Length",0)) or 0)
        # optional: rewrite model aliases
        try:
            j=json.loads(body); j["model"]=j.get("model","muse-spark-1.2"); body=json.dumps(j).encode()
        except: pass
        req = urllib.request.Request(UPSTREAM+"/responses", data=body,
            headers={"Authorization":f"Bearer {API_KEY}","Content-Type":"application/json","User-Agent":"Muse/0.2.1"})
        with urllib.request.urlopen(req) as r:
            data=r.read(); self.send_response(r.status)
            self.send_header("Content-Length", str(len(data))); self.end_headers(); self.wfile.write(data)
    def log_message(self,*a,**k): pass

http.server.HTTPServer(("127.0.0.1",8914),H).serve_forever()

OpenCode equivalent

OpenCode also supports custom OpenAI-compatible providers via opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "model": "my-gateway/muse-spark-1.2",
  "provider": {
    "my-gateway": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "My Gateway",
      "options": { "baseURL": "https://your-gateway.example.com/v1" },
      "models": {
        "muse-spark-1.2": { "name": "Muse Spark 1.2", "limit": { "context": 1048576, "output": 131072 } }
      }
    }
  }
}
opencode run -m my-gateway/muse-spark-1.2 "fix tests"

FAQ

Do I need a Meta account? No. muse auth set + --base-url is enough. muse login is only for Meta-hosted OAuth.

Does provider: meta mean I’m calling Meta directly? No—it's just the provider key. With --base-url it calls your gateway instead. Your Authorization: Bearer ... header is your gateway key.

What about images/PDFs? muse-spark-1.2 supports image, pdf, video as input modalities (1M context). Pass --image (repeatable) to muse exec.

Can I use this with OpenCode Go / other gateways? Yes—any OpenAI-compatible /v1/responses or /v1/chat/completions endpoint works; adjust the proxy’s upstream path.

Security

  • Never paste API keys as CLI args (they appear in ps). Use --api-key-stdin or env vars.
  • Don’t commit ~/.config/muse/auth.json or opencode auth files.
  • Gateways should use Bearer tokens over HTTPS only.

MIT — PRs welcome. Not affiliated with Meta.

About

Use Muse Code with any OpenAI-compatible gateway without Meta login (custom --base-url provider, proxy + OpenCode examples)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors