Skip to main content

MOPS

多节点出口代理系统 — 轻量级分布式出口负载均衡系统。

通过局域网内多台设备的 IP 聚合,绕过网关单 IP 限速。

功能特性

  • 多协议支持 — 同一端口自动识别 SOCKS5 / HTTP CONNECT / HTTP 代理(GET/POST),类似 Clash
  • 零配置发现 — 基于 mDNS,Server 广播、Client 自动发现,无需手动配置节点列表
  • 负载均衡 — random(随机)/ hash(会话保持)两种策略
  • 健康检查 — mDNS TTL 60s + 被动熔断(连续失败自动隔离,30s 后恢复)
  • 连接追踪 — Server 端记录所有 client 连接(IP、目标、状态),最近 5 分钟滚动历史
  • 系统代理 — 一键设置/取消系统全局代理(Windows / macOS / Linux)
  • REST API — 实时查看节点状态、流量统计、连接信息
  • Web Dashboard — AntV G6 拓扑图 + 暗色科技感界面,1s 轮询自动刷新

安装

# uv (推荐)
uv tool install carrot-mops

# pip
pip install carrot-mops

快速开始

# 安装 Python 依赖
uv sync

# 安装前端依赖(可选,仅开发 Dashboard 时需要)
cd web && bun install && bun run build && cd ..

# 出口机启动 Server(对外暴露出口)
uv run python -m mops run server

# 主力机启动 Client(本机代理入口)
uv run python -m mops run client

# 或者混合模式(同时跑 Server + Client)
uv run python -m mops run both

Client 启动后,默认监听 127.0.0.1:10081,自动发现局域网内的 Server 节点。

CLI 参考

mops                                              # 默认 both 模式启动
mops run        [--mode both] [--server-port 10080] [--client-port 10081] [--api-port 10082]
                 [--strategy random|hash] [--listen 127.0.0.1] [--weight 1] [--advertise <ip>]
                 [-c config.json]
mops service install                              # 注册服务
mops service start   [同 run 的参数] [-c config.json]
mops service stop                                  # 停止服务
mops service status                                # 查看服务状态
mops service uninstall                             # 卸载服务
mops service log    [-n 50] [-s keyword]           # 查看日志
mops dashboard     [--port 10100]                     # 独立 Dashboard
mops proxy on      [host:port]   [--host] [--port]  # 设置系统全局代理
mops proxy off                                     # 取消系统全局代理
mops proxy status                                  # 查看代理状态

参数说明

参数 说明 默认值
--mode 运行模式: server / client / both both
--server-port Server TCP 监听端口 10080
--client-port Client 代理监听端口 10081
--api-port REST API 监听端口 10082
--listen Client 本地绑定地址 127.0.0.1
--advertise mDNS 广播地址(通过路由表自动检测) auto
--strategy 负载均衡策略: random 或 hash random
--weight Server 权重 (仅 server 模式) 1
-c, --config 从 JSON 配置文件加载参数 —

端口分配

组件 参数 默认端口
Server TCP --server-port 10080
Client 代理 --client-port 10081
REST API --api-port 10082
Dashboard dashboard --port 10100

配置文件

mops run -c config.json               # 从文件加载所有参数
mops run -c config.json --strategy hash  # 文件 + 参数覆盖

配置文件格式(JSON):

{
  "mode": "both",
  "server_port": 10080,
  "client_port": 10090,
  "api_port": 10100,
  "listen": "127.0.0.1",
  "advertise": "",
  "strategy": "random",
  "weight": 1
}

合并优先级:CLI 参数 > -c 文件 > 默认值

代理协议

同一端口,自动识别协议类型,无需手动配置:

协议 客户端请求 用途
SOCKS5 0x05 0x01 0x00 握手 TCP 代理(HTTP/HTTPS/任意 TCP)
HTTP CONNECT CONNECT host:port HTTP/1.1 HTTPS 隧道
HTTP 代理 GET http://host/path HTTP/1.1 普通 HTTP 代理(GET/POST 等)

使用示例

curl 测试

# SOCKS5 代理
curl.exe -x socks5://127.0.0.1:10081 ifconfig.me

# HTTP 代理(支持 HTTP 和 HTTPS)
curl.exe -x http://127.0.0.1:10081 ifconfig.me
curl.exe -x http://127.0.0.1:10081 https://ifconfig.me

# 不走代理(直连对比)
curl.exe ifconfig.me

提示: Windows 上如果系统已配置代理(如 Clash 在 127.0.0.1:7890),测试时需加 --noproxy "*" 绕过。

设置系统代理

# 开启系统全局代理(默认 127.0.0.1:10081)
mops proxy on

# 指定地址(位置参数)
mops proxy on 192.168.1.100:20081

# 分开指定 host 和 port
mops proxy on --host 192.168.1.100 --port 20081

# 关闭并恢复原设置
mops proxy off

# 查看当前代理状态
mops proxy status

Clash / Clash Verge 配置

  1. 在 Clash Verge 中,选中订阅节点 → 点「编辑」,添加以下内容:
prepend:
  - type: 'socks5'
    name: 'SOCKS5 127.0.0.1:10081'
    server: '127.0.0.1'
    port: 10081
  1. 保存后,在代理页面右上角「链式代理」中选择 SOCKS5 127.0.0.1:10081 节点

说明: prepend 会在订阅节点前插入 MOPS 节点,通过链式代理让流量先走 MOPS,再走原有代理节点。

Web Dashboard

启动服务后,浏览器访问 http://127.0.0.1:10082/ 查看可视化面板:

Dashboard

  • 智能拓扑图 — AntV G6 5.x 拓扑图,dagre 从左到右布局,自动发现网络中的 Server 和 Client 节点
  • 两种模式:
    • 集成模式(mops run both):显示完整的 App → Client → Server → Internet 链路
    • 独立模式(mops dashboard):从网络推断 Client 节点,仅显示 Client → Server → Internet
  • 语义缩放:节点少时显示 hostname + IP:port 详情,节点多时自动隐藏标签避免重叠
  • 活跃连接 — 橙色流动虚线动画,1 秒自动刷新
  • 节点状态 — 绿色活跃、灰色熔断、暗色离线,实时更新

REST API

端点 说明
GET / Web Dashboard 页面
GET /api/server Server 状态 + 流量 + 连接信息 JSON
GET /api/dashboard 同 /api/server(别名)
响应示例
{
  "nodes": [
    {
      "ip": "192.168.1.100",
      "port": 10080,
      "api_port": 10082,
      "hostname": "Carrot-PC",
      "fails": 0,
      "status": "active",
      "total_up": 1024000,
      "total_down": 5120000,
      "active_conns": 3,
      "connections": [],
      "speed_up": 1024,
      "speed_down": 5120
    }
  ],
  "connections": [
    {
      "conn_id": "1",
      "client_ip": "192.168.1.50",
      "target_host": "example.com",
      "target_port": 443,
      "status": "active",
      "started_at": 12345.6
    }
  ],
  "total_up": 1024000,
  "total_down": 5120000,
  "speed_up": 1024,
  "speed_down": 5120,
  "active_conns": 3,
  "uptime": 3600,
  "mode": "both",
  "strategy": "random",
  "local_client": {"ip": "127.0.0.1", "port": 10081}
}

注意: /api/client 已移除。Client 端不再提供独立 API,所有信息通过 Server 的 /api/server 获取。

负载均衡

策略 说明
random 随机选择节点,流量最均匀
hash 按 client_ip:target_host 哈希,会话保持

健康检查

  • mDNS 广播 — Server 每 60 秒刷新 TTL,Client 自动感知节点加入/离开
  • 被动熔断 — 连续 2 次连接失败 → 节点移入观察池,30 秒后自动恢复

系统服务

Linux (systemd)

uv run python -m mops service install
uv run python -m mops service start --mode both --server-port 10080 --client-port 10090 --api-port 10100 --advertise 192.168.1.100
uv run python -m mops service status
uv run python -m mops service stop
uv run python -m mops service uninstall

Windows (sc)

uv run python -m mops service install
uv run python -m mops service start --mode both --server-port 10080 --client-port 10090 --api-port 10100 --advertise 192.168.1.100
uv run python -m mops service status
uv run python -m mops service stop
uv run python -m mops service uninstall

日志

日志自动保存到 ~/.mops/logs/mops.log(10MB 轮转,保留 7 天):

mops service log                # 最近 50 行
mops service log -n 100         # 最近 100 行
mops service log -s "error"     # 搜索关键词

开发

# Python
uv sync --extra dev
uv run pytest tests/ -v --cov=mops
uv run python build.py          # Nuitka 打包

# 前端 Dashboard
cd web
bun install                     # 安装依赖(Bun)
bun run dev                     # 开发模式(热更新)
bun run build                   # 构建到 src/mops/static/

项目结构

MOPS/
├── src/mops/
│   ├── __init__.py       # 版本号
│   ├── __main__.py       # CLI 入口
│   ├── protocol.py       # 共享常量 + NodeInfo dataclass
│   ├── stats/            # 统计模块(按职责拆分)
│   │   ├── __init__.py   # 重新导出
│   │   ├── traffic.py    # TrafficStats
│   │   ├── connection.py # ConnectionTracker
│   │   ├── registry.py   # NodeRegistry
│   │   └── history.py    # TrafficHistory
│   ├── tunnel.py         # 双向流量拷贝
│   ├── server.py         # TCP 透传 + mDNS + 连接追踪
│   ├── client.py         # SOCKS5 + HTTP CONNECT + HTTP 代理
│   ├── discovery.py      # mDNS 服务浏览
│   ├── scheduler.py      # 负载均衡 + 熔断
│   ├── dashboard.py      # 独立 Dashboard 服务
│   ├── api.py            # REST API + 统一 /api/dashboard 响应
│   ├── web.py            # 共享静态文件服务
│   ├── static/           # Vite 构建输出(G6 Dashboard)
│   │   ├── index.html
│   │   ├── dashboard.js
│   │   └── dashboard.css
│   ├── service.py        # 系统服务管理
│   └── proxy.py          # 系统代理配置
├── web/                  # 前端源码(Bun + Vite + TS + G6)
│   ├── package.json
│   ├── vite.config.ts
│   ├── vitest.config.ts
│   ├── playwright.config.ts
│   ├── index.html        # 双栏布局 (70/30)
│   └── src/
│       ├── main.ts       # 入口:1s 轮询 /api/dashboard
│       ├── types.ts      # TypeScript 接口
│       ├── format.ts     # 格式化函数
│       ├── data.ts       # API 获取 + toTopo 转换
│       ├── topo.ts       # G6 拓扑图(语义缩放 + 流动虚线动画)
│       ├── graph.ts      # G6 拓扑图模块(替代实现)
│       ├── cards.ts      # 服务器状态卡片
│       ├── style.css     # 工业暗色主题
│       ├── format.test.ts   # 格式化测试 (11)
│       ├── toTopo.test.ts   # 数据转换测试 (16)
│       └── graph.test.ts    # Graph 模块测试 (10)
│   └── e2e/              # Playwright E2E 渲染测试
│       ├── dashboard.spec.ts    # 基础 Dashboard 测试 (7)
│       ├── multi-node.spec.ts   # 多节点渲染测试 (16)
│       ├── multi-client-viz.spec.ts # 多客户端可视化测试 (5)
│       └── fixtures/mock-data.ts # 测试数据
├── tests/                # 290 个后端测试 + 37 个前端单元测试 + 28 个 E2E 渲染测试,≥85% 覆盖率
├── build.py              # Nuitka 打包脚本
├── pyproject.toml        # 项目配置 (hatchling)
├── .gitignore
└── LICENSE               # Apache License 2.0

许可证

Apache License 2.0

Metadata

Release files for carrot-mops 1.3.4

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

Source distribution (sdist)

Source distribution for carrot-mops 1.3.4
File Size Uploaded Provenance Actions
carrot_mops-1.3.4.tar.gz 831.4 kB With provenance Details for carrot_mops-1.3.4.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for carrot-mops 1.3.4
File Interpreter ABI Platform Actions
carrot_mops-1.3.4-py3-none-any.whl Python 3 none any Details for carrot_mops-1.3.4-py3-none-any.whl

Total release size: 1.3 MB

Release files / carrot_mops-1.3.4.tar.gz

Download URL carrot_mops-1.3.4.tar.gz
Size 831.4 kB
Tags Source
SHA-256 checksum
How to use checksums
9385dadfd7bc591b16f8080a3272fd90dcee2ce0db78423e4f3d3c590dfb887b
BLAKE2b-256 checksum
How to use checksums
e66e1af323ee7e95c48c14f93efbf0cb82092f31a33c52469532f387520631b2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jul 17, 2026.

Transparency log

Release files / carrot_mops-1.3.4-py3-none-any.whl

Download URL carrot_mops-1.3.4-py3-none-any.whl
Size 463.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
381d9ae4c95987d85c86d82c1d3b2fc2767457d1543abf712e3d1cde038a37cf
BLAKE2b-256 checksum
How to use checksums
1d4ba0ad173f4635610c87eeb3e91e9a48e5a7a7bad927ec67c2f5a0606e7a42
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jul 17, 2026.

Transparency log

Security for carrot-mops 1.3.4

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

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for carrot_mops-1.3.4.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 Jul 17, 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.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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