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

@hyydev/myops

v0.2.0

Published

Open source server control panel: manage a fleet of Linux and macOS machines over SSH from one dashboard

Readme

English · Tiếng Việt · 中文 · 한국어 · 日本語

面向自有 Linux 与 macOS 服务器的自托管控制面板:实时指标、nginx 站点、pm2 应用、Docker、数据库、 cron、防火墙、备份、SFTP 文件浏览器和完整的 SSH 终端 —— 全部在浏览器里完成,只依赖 SSH。

Next.js 16(App Router)嵌入自定义 Hono 服务,数据经 Prisma 存入 SQLite。

与众不同之处

  • 只用 SSH。 没有守护进程回连,不用额外开端口,不需要云账号。是 myOps 主动连出去,运行 myOps 的机器本身不需要公网地址。
  • 无二进制依赖的采集脚本。 可选的指标 agent 就是一个 POSIX shell 脚本 —— 目标机器上不用装任何 运行时。
  • 从不探测系统类型。 每条与系统相关的命令都写成 POSIX if/elif 分支后交给目标机器执行,所以同 一份代码在 Debian、RHEL、Arch、Alpine、SUSE 和 macOS 上都能跑。
  • 界面文字不来自服务端。 API 只返回消息键,由界面负责翻译,因此每个页面都同时存在越南语、英语、 中文、韩语和日语版本。

界面截图

| | | | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | 总览 —— 实时 CPU/内存/磁盘/网络、经 SSH 探测的服务栈、最近操作记录 | 应用 —— 通过 nvm 管理的 Node.js 版本与全部 pm2 进程,深色主题 | | Runner —— 在服务器上安装并注册 GitHub Actions 与 GitLab CI runner | 设置 —— 主密码、SMTP 与 Telegram、Web 推送、加密的配置备份 |

功能

| 模块 | 你能得到什么 | | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | 服务器 | 整个机群的卡片视图,含状态、CPU/内存/磁盘和标签筛选;用密码或 SSH 密钥(支持 passphrase)新增、编辑、删除服务器,保存前先测连接 | | 总览 | 系统信息、实时图表、服务栈状态、待更新的软件包、swap 管理、重启、临时命令、最近操作 | | 指标 | agent 在目标机器上每 15 秒采样一次,myOps 每 30 秒经 SSH 拉取;CPU/内存/网络/负载图表跨度 1 小时至 7 天 | | 站点(nginx) | 创建反向代理、静态和跳转 vhost,直接编辑原始配置,启用/停用,配置测试与 reload,签发/续期 Let's Encrypt 或导入自有证书 | | 应用(pm2) | 从 Git 仓库部署,start/stop/restart/reload,调整实例数,保存与恢复进程列表,按应用实时看日志,安装 pm2 及其开机自启单元 | | Docker | 容器的操作与详情、镜像的更新检查与拉取、卷、网络、磁盘占用、prune,以及带内联编辑器和日志的 Compose 栈 | | 数据库 | MySQL/MariaDB、PostgreSQL、MongoDB 与 Redis,原生安装或容器化皆可;建库、删库、导出、清空 Redis、安装与卸载引擎 | | Cron | 按用户列出、创建、编辑、启停、立即运行和删除任务,附人类可读的调度说明与单任务日志 | | 防火墙 | ufw 或 firewalld 规则、服务控制、fail2ban jail 与解封,以及自动生成的加固建议 | | 用户 | 系统账号、用户组、home 与 shell、重置密码、每个用户的授权 SSH 公钥 | | Runner | 把 GitHub Actions 与 GitLab CI runner 注册成服务并加以控制 | | 备份 | restic 仓库配置、定时与手动执行、可选先导出数据库、浏览快照、恢复、导出与 forget | | 可用性监控 | 从 myOps 主机发起的 HTTP/TCP 探测:状态码、正文匹配、响应时间、24 小时可用率与 TLS 到期;宕机和恢复时都会通知 | | 文件 | 浏览、查看和编辑文本文件,拖拽上传、下载、重命名、chmod、删除 —— 全部走 SFTP | | 终端 | 基于 WebSocket + xterm.js 的真实 SSH shell,自动适配尺寸,切换路由时标签页保持存活,带会话数量上限与空闲超时 | | 日志 | 发现日志源(journald 或普通文件),经 WebSocket 实时跟踪,按级别与关键词过滤,可下载 | | 端口 | 监听端口与 CPU 占用最高的进程,按 PID 结束进程(myOps 拒绝杀掉自己的 SSH 会话) | | 磁盘 | 文件系统的使用率与 inode、块设备、用 du 找出目录里到底是什么占了空间、一键清理缓存与轮转日志,以及给空闲磁盘分区+格式化+挂载 | | 机群批量 | 按标签或手动挑选服务器,对它们执行同一个动作(自定义命令、系统更新、重启、nginx/pm2 reload、Docker prune、备份),每台一份日志 | | 维护窗口 | 为单台服务器或整个机群设定静默时段,期间屏蔽全部通知 | | 告警 | 按指标设定阈值规则,通过邮件(SMTP)、Telegram 和 Web 推送送达,每次越界只触发一次 | | 设置 | 主密码、带测试按钮的 SMTP 与 Telegram 凭据、推送通知、查看并复制主密钥与 MCP token、整份配置的加密导出/导入 | | MCP | /mcp 上的 Model Context Protocol 端点:AI 助手可查看全机群的指标、子系统状态与日志,并执行重启、备份、更新和部署;token 首次运行时自动生成 | | 安全 | 单一主密码(argon2id)、httpOnly 会话 cookie、SSH 凭据用 AES-256-GCM 加密、所有改动状态的操作都写审计日志 | | 其他 | 可安装为 PWA 并支持 Web 推送、Cmd/Ctrl + K 命令面板可跳到任意服务器与页面、明暗主题、五种语言 |

架构

Browser ──http──► Hono ──► /api/*         REST
        └──ws────►      ──► /ws/terminal       ⇄ SSH shell
                        ├─► /ws/agent-install  agent install log
                        ├─► /ws/app-logs       live log stream
                        └─► everything else → Next.js

MCP client ──http──► Hono ──► /mcp        read + operate tools (bearer token, generated on first run)

myOps ──ssh──► target: myops-agent (systemd timer / cron)
                        └─ writes /var/lib/myops-agent/metrics.jsonl (ring buffer)

agent 从不主动外连 —— 是 myOps 通过 SSH 进去读文件,所以 myOps 主机不需要公网地址,目标机器除 SSH 外不用开任何端口。myOps 停机期间 agent 照常采样;下次拉取会从记录的游标继续,图表因此不会断档。

| 路径 | 职责 | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | server.ts | 自定义服务:Hono 先接请求,截走 /ws/* 的 upgrade,其余(含 HMR)转给 Next;同时启动调度器 | | src/server/api.ts | 挂在 /api basePath 的 Hono 应用、会话中间件、集中式错误处理、Server-Timing | | src/server/routes/ | 只负责 HTTP 与 WebSocket:authserverssettingsmetricsfleetopsfilesterminalagentlog-tailmcp | | src/server/services/ | 所有会碰到目标机器的命令:sshshellplatformjobscachecrypto,以及每个领域一个 service | | src/server/mcp/ | 建立在 service 之上的 MCP 工具面 —— tools.ts 只读、actions.ts 写,只要 MYOPS_MCP_TOKEN 有值就在 /mcp 提供服务 | | agent/myops-agent.sh | POSIX shell 编写的 agent,目标机器无需任何运行时 | | prisma/schema.prisma | Setting、Session、Server、Credential、MetricSample、Job、AuditLog、SslCert、UptimeCheck、UptimeSample、Maintenance、BackupConfig、NotifyRule、PushSubscription | | src/app/(app)/ | 需要登录的路由组:机群面板、单机各页面、批量执行、维护窗口、全局设置 | | src/components/ui/ | 设计系统 —— 一个文件一个组件,由 index.ts 统一再导出 | | messages/ | vi/en/zh/ko/ja.json,键集完全一致,按页面分 namespace |

分层规则:route 里不写任何 SSH 逻辑,客户端除类型外绝不 import service。

快速开始

不用克隆仓库,最快的试用方式:

npx @hyydev/myops              # http://localhost:3000

全局安装(npm i -g @hyydev/myops)会把更短的 myops 命令放进 PATH。

状态文件放在 ~/.myops —— 含主密钥的 .env 与 SQLite 文件 —— 所以升级不会丢。PORTHOSTNAME 可覆盖默认值,其余选项见 myops --help

从源码运行,用于开发或长期部署:

git clone <repo> myops && cd myops
yarn install
yarn dev                          # http://localhost:3000

配置到此为止。yarn devyarn start 都会从 .env.example 生成 .env、在缺失时生成 MYOPS_MASTER_KEY,并在服务启动前应用迁移(见 数据库)。已存在的密钥永远不会被重新生成 —— 换一把新的会让所有已存凭据无法解密。

请备份这把密钥。 myOps 保存的每一份 SSH 凭据都用它加密,且没有任何找回途径。副本请放在 prisma/dev.db 以外的地方。

首次运行时 myOps 会跳转到 /setup 设置主密码。之后:添加服务器 → 测试连接 → 安装 agent。

环境要求

  • myOps 主机上装有 Node.js 20 或更高版本
  • 能 SSH 到每台目标机器,目标机器有 POSIX shell,且改动状态的操作可用 sudo/root

myOps 执行的是非交互式命令,因此使用 sudo -n:SSH 账号必须要么是 root,要么拥有免密 sudo。 大多数 Linux VPS 本来就是 root,无需额外配置。macOS 上则必须自行配置,因为默认禁止 root 登录 SSH,而管理员账号仍会被要求输入密码:

# 在目标 macOS 机器上执行
sudo visudo -f /etc/sudoers.d/myops     # 加入:<user> ALL=(ALL) NOPASSWD: ALL
sudo systemsetup -setremotelogin on     # 若远程登录未开启则打开

实在无法使用免密 sudo 时,myOps 也可以代为输入密码。用密码登录的账号会自动复用该密码;用密钥登录 的账号可以在服务器表单里填 sudo 密码。无论哪种方式,这个密码都和其他凭据一样被加密、绝不由 API 返回,并通过 stdin 喂给 sudo -S,所以它不会出现在命令行或 sudo 日志里。

myOps 不会盲目下手:测试连接会如实报告该账号究竟能做什么 —— root、免密 sudo、需要密码的 sudo, 还是完全没有 sudo —— 只有确实会提示输入密码的机器才会退回 sudo -S

支持的系统

所有开启 SSH 的 Linux 发行版,外加 macOS。myOps 不会预先判断系统类型:每条与系统相关的命令都在 src/server/services/platform.ts 里写成 POSIX if/elif 分支,由目 标机器在一次往返内自行选择分支。

| 层面 | 支持范围 | | --------- | ----------------------------------------------------------------------- | | 包管理器 | apt-getdnfyumzypperpacmanapk、Homebrew | | init 系统 | systemd、OpenRC、launchd(经 brew services)、sysvinit | | 防火墙 | ufw(Debian、Arch)、firewalld(RHEL、SUSE)、应用防火墙(macOS) | | Cron | croncrondcronie、busybox crond | | 系统日志 | journald,或无 systemd 时的 /var/log/syslog · /var/log/messages | | 机器指标 | Linux 上读 /proc;macOS 上用 sysctl + vm_stat + netstat + top | | CPU 架构 | x86_64aarch64/arm64(含 Apple Silicon) |

有几处限制来自上游,而非 myOps 本身:

  • MongoDB 官方仓库只提供 deb 与 rpm;在 Arch 和 Alpine 上请用 Docker 模式。
  • GitHub Actions runner 会把自己注册成 systemd 服务,因此该按钮只在 systemd 机器上有效。
  • 用户页面依赖 shadow 工具链(useraddusermodchpasswd);Alpine 需要额外装 shadow 包,macOS 用的是 dscl,所以该页面暂时不可用。
  • Nginx:只有 Debian 默认带 sites-enabled。创建站点时,若 nginx.conf 里没有对应的 include 行,myOps 会往 conf.d 里补一条,因此 vhost 在各发行版都能生效。macOS 上 Homebrew 把 vhost 放在 $(brew --prefix)/etc/nginx/servers;myOps 能统计到它们,但站点页面写入时仍按 Linux 的目录 结构。
  • macOS 上的防火墙、备份与证书目前只读:操作按钮说的仍然是 ufw/firewalld 与 certbot。

有三个页面只支持 Linux —— 防火墙用户CI/CD runner —— 当服务器报告的是别的系统 (macOS、BSD、Windows)时,侧边栏对应入口会变灰失效,命令面板里也不再出现,手动输入 URL 则会落到一 个解释原因的页面。若 agent 尚未报告系统类型,所有页面都保留:myOps 绝不靠猜测隐藏功能。

Agent

在界面里安装(总览页 → 安装 / 更新 agent)。myOps 会:

  1. 经 SFTP 把 agent/myops-agent.sh 复制到 /usr/local/bin/myops-agent
  2. 创建 myops-agent.service.timersystemctl enable --now(周期 15 秒)。
  3. 目标机器没有 systemd 时,退回到每分钟跑四次的 cron。
  4. 把登录用户记进 /var/lib/myops-agent/owner(root 所有,0644)。agent 由 timer 或 cron 以 root 身份运行,此时 SUDO_USER 为空,没有这个文件就找不到装在登录用户家目录里的 nvm、Homebrew 或 Docker Desktop 可执行文件。

agent 只读取 /proc/stat/proc/meminfo/proc/net/dev/proc/loadavg/proc/uptimedf -P /(macOS 分支用 sysctlvm_statnetstat -ibtop),然后追加进一个 2000 行的环形 缓冲(约 400KB)并自行截断。卸载只需点一个按钮。

没装 agent 的服务器仍会通过每轮一条 SSH 命令上报内存/磁盘/负载;只有 CPU% 会是空的,因为它需要连续 两次采样。

MCP 服务

myOps 可以通过 Model Context Protocol 把机群暴露给 AI 助手,让模 型直接看到真实运行状况,而不是听别人转述 —— 顺手把小问题修掉,不必由人来传话。

大部分工具只读。其中十个能操作机群,且能做的事是刻意收窄的:重启应用、容器、compose 栈和服务,启停 站点与 cron 任务,执行备份,签发证书,安装更新和部署。没有任何工具能删除站点、应用、容器、数据库 或用户,不能重启机器,也没有执行任意命令的工具。 每次操作都写审计日志,可能中断服务的那些还带 destructiveHint 标记,客户端可据此先向人确认。

token 和主密钥一样在首次运行时自动生成,写入 .envMYOPS_MCP_TOKEN。你不需要手工产出:首页的 连接 MCP 会直接给出填好 token 的客户端配置和 CLI 命令,设置 → 密钥里可以看到原始值。

要关掉这个端点,把值清空后重启。myOps 只在 .env 里完全没有这一行时才生成 token,所以留空会被视为 明确的关闭意图,永远不会被自动填回。长度不足 24 个字符会打印警告,并让 /mcp 返回 404。

把客户端指向 http://localhost:3000/mcp,带上 Authorization: Bearer <token>。Claude Code 的写法:

claude mcp add --transport http myops http://localhost:3000/mcp \
  --header "Authorization: Bearer $MYOPS_MCP_TOKEN"

| 工具 | 回答什么 | | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | | list_servers | 整个机群及其最新的 CPU/内存/磁盘采样。从这里开始 —— 它返回其他工具都要用的 serverId | | server_detail | 连接信息、硬件、系统、已装服务栈,以及各板块的计数 | | server_metrics | 1 小时至 7 天的 CPU/内存/swap/磁盘/负载/网络序列,读自 myOps 数据库 | | server_state | 经 SSH 实时探测的某个子系统:nginx、apps、docker、databases、firewall、cron、node、ports、disk、runners、users、backup、swap、sshKeys | | check_updates | 待更新的系统软件包、其中多少是安全更新、过期的服务栈组件,以及是否需要重启 | | monitoring | 可用性检查及其最近结果与 TLS 到期时间、告警规则及是否正在触发、生效中的维护窗口 | | uptime_history | 某个可用性检查已记录的探测结果:通/断、响应时间、状态码 | | log_sources / read_logs | 先看有哪些日志可跟踪,再按级别、关键词和时间窗口去读 | | app_logs / container_logs | 某个 pm2 应用或某个 docker 容器的日志尾部 | | list_files | 经 SFTP 列一个目录 —— 名称、大小、权限、mtime。文件内容是刻意不暴露的 | | list_jobs / recent_activity | 后台任务及其输出,以及所有改动状态操作的审计记录 | | fleet_overview | 机群整体:在用的标签,以及最近一次跨多台服务器执行的动作 |

会改动状态的工具:

| 工具 | 做什么 | | --------------------------------- | ------------------------------------------------------------------------------------ | | app_action / container_action | pm2 应用的 start、stop、restart、reload;容器的 start、stop、restart、pause、unpause | | stack_action | docker compose 栈的 up、start、stop、restart 或 pull | | site_action / nginx_action | 启用或停用某个 vhost;测试、reload 或重启 nginx | | cron_action | 启用、停用或立即运行某个 cron 任务 | | run_backup | 执行已配置的 restic 备份,可选先导出数据库 | | issue_cert | 为某个域名签发 Let's Encrypt 证书,或续期所有到期的证书 | | update_packages / deploy_app | 安装待更新的软件包,或重新部署一个 pm2 应用 —— 都是后台任务,用 list_jobs 跟进 |

开启之前有两件事值得知道:

  • 日志内容属于不可信输入。 容器名、进程名和日志行都来自你无法掌控的软件,而它们会进入模型的上 下文 —— 旁边就摆着能重启和部署的工具。一行读起来像指令的日志并不是指令。真正限制损害的是动作清 单:里面没有任何工具会删数据或执行任意命令,且每一次调用都被审计。如果你更想要“注入了也无处下 手”的那种保证,就别开这个端点。
  • token 是覆盖整个机群的操作凭据。 它能读出每台服务器的主机名、开放端口、已装软件包和日志内容, 也能在所有机器上重启和部署。请像对待主密码一样对待它,别在没有 HTTPS 的情况下把端点放到公网。

多语言

基于 next-intl,不使用 i18n 路由 —— 语言来自 myops_lang cookie 而不是 URL 前缀,因此所有路径保持不变。默认越南语,另带英语、中文、韩语和日语。

// Client component
const t = useTranslations("firewall");
t("ufwSummary", { fw: "UFW", status: "on", rules: 12, jails: 3 });

// Server component
const t = await getTranslations("meta");

翻译文本放在 messages/<locale>.json —— 每种语言一个文件,键集完全一致,使用 ICU 语法(含英语复数) 。键在构建期由 src/global.d.ts 里的 AppConfig 声明做类型校验 —— 写错就是 TypeScript 错误。切换语 言用 useSetLocale(),它写入 cookie 后调用 router.refresh()(消息在服务端解析,必须走一次往返)。

新增语言:在 src/lib/lang.tsLOCALES 里加上它,更新 parseLang,然后创建 messages/<locale>.json

数据库

schema 以带版本的迁移随源码一起走,放在 prisma/migrations/scripts/db-setup.tspredev / prestart 钩子触发,所以新克隆的仓库只要 yarn dev,已有安装则自动补上缺失的迁移。

| 情况 | 脚本会做什么 | | ------------------------------- | ------------------------------------------------- | | 还没有 dev.db | 创建文件,再 prisma migrate deploy 应用全部迁移 | | 数据库是用 db push 建的(旧) | 把 0_init 标记为已应用(baseline),再补其余 | | 已经在用迁移 | 只应用缺失的那些 |

改完 prisma/schema.prisma 后,用 yarn db:migrate --name <name> 生成迁移并提交产生的目录。不要 再用 prisma db push:它就地改数据库,不留下任何可供其他机器应用的东西。

脚本

| 命令 | 说明 | | -------------------------------- | -------------------------------------- | | yarn dev | 开发模式的自定义服务(tsx watch) | | yarn build / yarn start | 生产构建与运行 | | yarn format / format:check | Prettier 写入 / 检查 | | yarn lint / yarn typecheck | ESLint 与 tsc --noEmit | | yarn db:migrate --name <name> | 根据 schema 变更生成迁移 | | yarn db:setup | 手动应用迁移(dev/start 也会做) | | yarn db:studio / db:generate | Prisma Studio · 重新生成 Prisma Client |

任何改动收尾前都请跑一遍 yarn format && yarn lint && yarn typecheck

环境变量

| 变量 | 必填 | 说明 | | ----------------------- | ---- | ---------------------------------------------- | | DATABASE_URL | 是 | file:./dev.db(相对 prisma/schema.prisma) | | MYOPS_MASTER_KEY | 是 | 凭据加密密钥,至少 32 个字符 | | MYOPS_HOME | 否 | .env 与 SQLite 文件的存放位置 —— 见下文 | | PORTHOSTNAME | 否 | 默认 3000 / localhost | | MYOPS_INSECURE_COOKIE | 否 | 在局域网用纯 HTTP 跑生产环境时设为 1 | | MYOPS_MCP_TOKEN | 否 | MCP 端点凭据;首次运行时自动生成 |

MYOPS_HOME 决定那两个无可替代的文件放在哪里。不设置时,若工作目录里能找到 .envprisma/schema.prisma,myOps 就用工作目录 —— 源码检出和 Docker 镜像因此都维持原有位置。其他情况下 退回 ~/.myops,这样即使代码装在一个随时会被替换的目录里,密钥也能跨版本留存。

数据保留

原始指标保留 24 小时;超过之后每 5 分钟只留一个采样;超过 30 天则删除。清理任务每小时跑一次,同时 清掉过期会话。

安全须知

  • 弄丢 MYOPS_MASTER_KEY 就等于弄丢全部 SSH 凭据 —— 没有找回途径。请把密钥备份到 prisma/dev.db 之外的地方。
  • API 永远不返回凭据本身,只返回一个 hasCredential 标记。
  • 主机密钥采用首次使用即信任:第一次连接会记下 SHA256 指纹,之后每次都必须一致,因此一台开始用不同 密钥应答的机器会被拒绝,而不是把已存凭据递过去。重装过的机器需要在该服务器的设置页里手动忘记一次 旧密钥。
  • 把 myOps 暴露到局域网之外必须在前面加带 HTTPS 的反向代理:会话 cookie 以及全部文件与终端操作都走 这条连接。
  • 文件操作与终端会话都会写入 AuditLog(终端按键内容不记录)。
  • MYOPS_MCP_TOKEN 是覆盖整个机群的操作凭据 —— 见 MCP 服务。它在首次运行时生成;在 .env 里清空并重启后,/mcp 就不复存在。

参与贡献

先看 CONTRIBUTING.md,再看 AGENTS.mdconventions.md —— 它们定义了本代码库遵循的分层、命名、i18n 与注释规则。目前还没有 测试框架,验证方式是 yarn format && yarn lint && yarn typecheck

发现安全问题?请不要开公开 issue —— 见 SECURITY.md

许可证

采用 Apache License 2.0。你可以使用、修改并自托管 myOps,包括商业用途,只要保留许可证与 版权声明,并注明你所做的修改。


Copyright © 2026 myOps. Licensed under the Apache License, Version 2.0.