Files

133 lines
5.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# mirasim-relay
把 Mirasim 桌面版内置的「本地中继」单独拆出来,让 Linux 也能用自己账号的额度。
Mirasim 官方只发 macOS / Android 包,但它的 `SHA256SUMS` 里其实还有没在下载页挂出来的
`mirasim-server-linux-x64-0.0.146.tar.gz`。这个脚本就是从那份官方 Linux 构建里把中继部分
(登录 → 设备签名 → 转发)重新实现出来的,行为跟桌面版一致。
中继本身说的是 **Anthropic 的协议**,同时也提供 **OpenAI Responses 协议**Codex 用的那个),
按路径分发,凭据完全一样。所以 Claude Code 和 Codex 都能直接指过来。
## 快速开始
```sh
./mirasim-relay login # 邮箱验证码 / GitHub / Google / 直接粘 token
./mirasim-relay status # 看账号、有效期、剩余额度(两条协议各探一次)
./mirasim-relay serve # 起本地中继,默认 127.0.0.1:8787
```
另开一个终端,Claude Code
```fish
set -gx ANTHROPIC_BASE_URL http://127.0.0.1:8787
set -gx ANTHROPIC_AUTH_TOKEN mirasim-relay-managed-credential
claude
```
Codex
```sh
./mirasim-relay codex # 等价于 codex,但指向中继
./mirasim-relay codex -- exec "写个 fib" # -- 后面原样透传给 codex
```
bash / zsh 用 `./mirasim-relay env --bash`,它会按当前 shell 输出对应语法。
`ANTHROPIC_AUTH_TOKEN` 的值是什么都无所谓——每个请求都会被换成真正的中继凭据,
但大多数 agent 不设这个变量就不发请求,所以得给一个占位值。
## 命令
| 命令 | 说明 |
| --- | --- |
| `login [--method email\|github\|google\|token] [--email ...]` | 登录并保存凭据 |
| `serve [--port 8787] [--host 127.0.0.1] [--agent claude\|codex] [-v]` | 起本地中继,`-v` 打印每条请求 |
| `codex [--port 8787] [--model ...] [--effort ...] [-- <codex 参数>]` | 拉起真正的 codex,指向中继 |
| `status [--model ...]` | 账号信息 + 探测两条协议的额度 |
| `env [--port 8787] [--bash] [--codex]` | 输出环境变量 |
| `logout` | 清除登录态(设备密钥保留) |
不给 `--agent` 时,`x-mirasim-agent` 按请求路径自动推断(`/v1/messages``claude`
`/v1/responses``codex`),跟桌面版的上报一致;给了就固定。
## 两条协议
中继按路径分发,跟桌面版 `server.cjs` 里的分类函数(`tD()`)一字不差:
| 路径 | 协议 | 谁在用 |
| --- | --- | --- |
| `POST /v1/messages` | Anthropic Messages | Claude Code |
| `POST /v1/responses` | OpenAI Responses | Codex`wire_api = responses`|
| `POST /v1/chat/completions` | OpenAI Chat Completions | 各种 OpenAI 兼容客户端 |
| `GET /v1/models` | — | 通用 |
Codex 没有「base url 环境变量」这种东西,它只认 config.toml 里的 provider 块。桌面版的做法
是在命令行上现场注入,本脚本照抄:
```
codex -c model_providers.apodex.name=apodex \
-c model_providers.apodex.base_url=http://127.0.0.1:8787/v1 \
-c model_providers.apodex.wire_api=responses \
-c model_providers.apodex.env_key=OPENAI_API_KEY \
-c model_provider=apodex
```
加上 `OPENAI_API_KEY=mirasim-relay-managed-credential``mirasim-relay codex` 就是把这一串
拼好再 exec`./mirasim-relay env --codex` 只打印不执行。
中继侧的 codex 模型:`gpt-5.6-sol`(默认)、`gpt-5.6-terra``gpt-5.6-luna`
前两个支持到 `ultra` 档推理强度,`luna``max`;默认 `xhigh`
顺带一提,`POST /backend-api/codex/responses`(ChatGPT 后端那条路径)分类函数里也认,
但中继本身对它返回 404 —— 桌面版只在 MITM 抓 `chatgpt.com` 时才会走到那儿。
## 它到底做了什么
```
agent ──► 127.0.0.1:8787 ──► https://mirasim-relay.mirofish.ai ──► Anthropic / OpenAI
(本脚本)
```
每个请求经过时:
1. **换凭据** —— 删掉 agent 自己的 `authorization` / `x-api-key`,换成你的账号凭据。
2. **续期** —— access token 距过期不足 15 分钟就用 refresh token 走 `/auth/refresh` 换新的。
3. **设备签名** —— 首次运行生成一对 Ed25519 密钥,向 `/v1/device/session` 换一张短期
ticket;拿到后每个请求都按 `mrs-sig-v1` 签名(`x-mirasim-device/ts/nonce/sig`)。
中继若不支持(404/501)就退回裸 token,跟桌面版的降级路径一样。
4. **收敛 header** —— 丢掉 hop-by-hop 头;`anthropic-beta` 只保留中继真正认的
`context-1m-2025-08-07`,其余丢弃。其它头(含 `openai-beta`)原样透传。
响应是流式透传的,SSE 不会被缓冲。客户端中途断开(Ctrl-C、取消一轮对话、关掉 pane)
只会掉这一个请求,不会影响服务端本身。
## 配置
凭据存在 `~/.config/mirasim-proxy/config.json``0600`),里面有账号 token、refresh token
和设备私钥。换目录用 `MIRASIM_PROXY_HOME`
其它可覆盖项:`MIRASIM_RELAY_BASE_URL``MIRASIM_LOGIN_URL``MIRASIM_APP_VERSION`
`MIRASIM_NODE`(指定 Node 运行时)、`MIRASIM_CODEX_BIN`(指定 codex 可执行文件)。
## Node
系统没装 Node 也能跑:`vendor/node` 是官方 Linux 包里那个 v22.23.1,启动器按
`$MIRASIM_NODE` → PATH 上的 `node``vendor/node` 的顺序找。
装了自己的 Node(>= 20)的话可以把 `vendor/` 删掉。
## 测试
```sh
./vendor/node test.mjs
```
21 个用例,不需要登录,也不会碰真实凭据:签名规范串、deviceId 推导、header 改写、
配置文件权限、路径分类、Codex provider 块,以及四个断连用例(起一个假上游 + 真的
proxy,客户端在流中间 / 上游还没回 header 时 / 上传中途消失,验证服务端还活着)。
## 注意
Mirasim 赠送额度的说法是 “Claude Code Max / Codex Pro usage **inside Mirasim**”。
把中继拆出来给别的 agent 用,大概率不符合他们的服务条款,最坏情况是封号。
自行判断。