mcpField
S
SafeGrd

SafeGrd

远程服务
safegrd.dev文件与存储03 天前更新

关于 SafeGrd

SafeGrd 为数据库、目录和 IMAP 邮箱提供加密备份与恢复测试,适合需要检查备份可恢复性并防止误删的运维团队。它提供本地和远程 MCP 服务,且工具不能删除备份。

主要功能

  1. 01加密并压缩备份
  2. 02定期恢复演练与校验
  3. 03支持数据库、目录和 IMAP
  4. 04破坏性命令前创建锁定快照
  5. 05恢复数据库或单个文件

适用场景

  1. 01验证最新备份能否恢复
  2. 02在数据库变更前保护数据
  3. 03找回目录中的特定文件

MCP 相关

提供本地 stdio MCP 服务和远程 HTTP MCP 服务。本地服务使用主机配置和密钥执行状态查询、备份、验证、恢复与导出;远程服务可读取备份和演练记录,并请求立即备份或演练。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://safegrd.dev/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

全部服务地址
Streamable HTTPhttps://safegrd.dev/mcp需要授权
安装包
ocighcr.io/safegrd/cli:0.0.29

工具

详细介绍

SafeGrd CLI(safegrd)

CI Go Version License: BSL 1.1

safegrd 可备份 PostgreSQL、MySQL、MariaDB、MongoDB 和 SQLite 数据库、目录树以及 IMAP 邮箱。每份备份都会在执行备份的主机上使用 zstd 压缩并通过 age 加密,然后写入启用了 Object Lock 的 S3 兼容存储。系统还会按计划还原备份,以检查每个表、行和文件是否都已恢复。

它是 SafeGrd 的 CLI 和守护进程。文档位于 safegrd.dev/docs,所有命令和标志都列在命令参考中。

  • 备份从你的主机直接传到存储。 远程服务会收到每份备份的记录(执行时间、大小、摘要和锁定到期日期),以及每次还原测试的签名结果。数据绝不会经过远程服务。
  • 由你决定谁持有密钥。 默认情况下,远程服务会密封保存你的密钥,只向已注册的主机释放,因此即使丢失一台主机,你也能还原备份。使用 enroll --key-custody local 时,只有你能解密这些备份。
  • 还原会经过测试。 Fire Drill 会将最新备份还原到临时数据库或目录中,将其表、行和摘要与备份内容进行比较,并为结果签名。
  • Agent 无法删除备份。 safegrd guard 会在破坏性命令运行前创建一份已锁定的快照,而个人访问令牌无法删除备份或缩短其锁定时间。

安装

安装脚本(Linux 和 macOS)
curl -fsSL https://safegrd.dev/install.sh | sh

脚本会检测你的操作系统和架构,下载对应的发行版归档文件,将其与该发行版的 checksums.txt 核对,然后把 safegrd 安装到 /usr/local/bin(无法使用 sudo 时则安装到 ~/.local/bin)。此仓库中的脚本是 install.sh;https://raw.githubusercontent.com/safegrd/cli/main/install.sh 提供相同的文件。

在终端中运行时,脚本接着会提示将此机器连接到远程服务:通过浏览器登录、询问由谁持有加密密钥,然后运行 safegrd enroll。登录时会显示一个 URL 和一个代码,你可以在任何设备的浏览器中打开,因此通过 SSH 或 PuTTY 连接的服务器也能以相同方式完成登录。没有终端时(CI、cloud-init、cron),脚本只会安装,不会继续操作。

选项通过环境变量设置,并写在管道后的 sh 命令上。若将它们写在 curl 前面,它们只会应用于 curl,脚本不会获取到这些变量:

curl -fsSL https://safegrd.dev/install.sh | VERSION=v0.0.3 sh                  # pin a release
curl -fsSL https://safegrd.dev/install.sh | SAFEGRD_INSTALL_DIR=~/.local/bin sh  # no sudo
curl -fsSL https://safegrd.dev/install.sh | SAFEGRD_NO_SETUP=1 sh               # install only
变量作用
VERSION要安装的发行版标签。默认值:最新发行版。
SAFEGRD_INSTALL_DIR二进制文件的安装位置。
SAFEGRD_NO_SETUP=1仅安装;不提示登录和注册。
SAFEGRD_FORCE_INSTALL=1即使已安装指定的发行版,也下载并安装。
SAFEGRD_PROJECT要将此机器注册到的项目 ID 或标识。
SAFEGRD_STORAGE项目没有存储桶时,备份的存放位置:hosted 或 local。
SAFEGRD_CLAIM控制台为此机器显示的认领码。它包含项目、备份存放位置以及要保护的对象,因此注册时会将这些内容写入配置,不再询问。需要使用带有 --claim 选项的 enroll 命令的发行版;较旧的版本会停止并说明原因。
SAFEGRD_NODE_NAME显示此机器时使用的名称。
SAFEGRD_KEY_CUSTODYlocal 会将此主机的密钥保存在主机上。不使用该选项时,远程服务会密封保存密钥,并只向已注册的主机释放。
SAFEGRD_SERVER_URL用于登录和注册的远程服务。默认值:https://safegrd.dev。
Homebrew(macOS 和 Linux)
brew install safegrd/tap/safegrd

此 formula 安装的发行版归档文件与脚本安装的相同。

Go
go install github.com/safegrd/cli/cmd/safegrd@latest
容器镜像

ghcr.io/safegrd/cli 可在 linux/amd64 和 linux/arm64 上运行,并包含 pg_dump、mysqldump 和 mongodump,以及 PostgreSQL 18 服务,因此演练可以将数据库恢复到卷上的临时集群中。标签标明 Postgres 客户端版本:<version>-pg18 可读取 Postgres 18 和所有更早版本的服务。发布版本使用 cosign 签名(无密钥,来自此仓库的发布 工作流):

cosign verify ghcr.io/safegrd/cli:<version>-pg18 \
  --certificate-identity-regexp 'https://github.com/safegrd/cli/.github/workflows/release.yml@.*' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

packaging/compose 会在数据库旁运行守护进程, packaging/kubernetes 会以 CronJob 形式运行 daemon run --once, 而 packaging/helm/safegrd 会以 Deployment 形式运行守护进程。 每个配置都标明构建时使用的发布版本,例如 ghcr.io/safegrd/cli:0.0.10;更改 标签即可升级。

发布压缩包,或从源代码构建

Linux 和 macOS(amd64、arm64)的静态二进制文件及其 SHA-256 校验和位于 发布页面。构建方法:

git clone https://github.com/safegrd/cli.git && cd cli
make build

快速入门

1. 创建配置和密钥

如果你让安装脚本连接此机器,则可跳过此步骤:脚本已经写入密钥对和 ~/.safegrd/config.yaml,而 init 会拒绝覆盖它们。

# writes an age X25519 keypair and ~/.safegrd/config.yaml
safegrd init \
  --database-url "postgres://postgres:password@localhost:5432/myapp_prod" \
  --storage local \
  --local-path ./backups \
  --retention-days 14
2. 连接到远程服务(可选)
# Prints a URL and a code: open it in a browser on any device, including over SSH
safegrd login

# Register this machine, generating its encryption key if it has none.
# --key-custody decides whether the server keeps a copy (safegrd) or not (local)
safegrd enroll --key-custody local

# A host that should encrypt but never decrypt: make the key pair on your laptop,
# then put only the printed public key in the host's encryption.public_key
safegrd keygen --out ~/.safegrd/keys/prod.key

# Headless / CI: a Personal Access Token instead of the browser
safegrd enroll --token "sg_pat_..."

# Or with the claim code the console's setup shows: the project, where backups go and
# the surfaces are written into ~/.safegrd/config.yaml, and the key stays on this machine
safegrd enroll --claim <code>
safegrd doctor                # every surface opens from this host; the console shows the result
safegrd daemon run --once

# Later, on an enrolled host: add the surfaces named for it in the console
# (Add surface on its row). Only adds; the old config is kept as config.yaml.bak
safegrd claim
safegrd daemon restart

# Verify the active session
safegrd whoami
3. 备份
# dumps, compresses, encrypts with age on this host, and writes to locked storage
safegrd backup
4. 运行 Fire Drill
# restores into an empty database and checks every table's row count
safegrd verify \
  --snapshot snap-20260919-01 \
  --sandbox-target "postgres://postgres:password@localhost:5432/ephemeral_test_db"
5. 恢复
safegrd restore \
  --snapshot snap-20260919-01 \
  --target "postgres://postgres:password@localhost:5432/myapp_recovered"
6. 在一台主机上无人值守地保护多个对象

~/.safegrd/config.yaml 中 surfaces: 下的每个条目都是一个受保护对象,而 safegrd daemon install 会按各自的计划运行它们。surface 的 credential 区块说明 其密钥的来源;配置中不会保存密钥:

surfaces:
  - id: app-primary
    type: postgres
    schedule: "@daily"
    credential:
      from: env                 # or: command (with run), file (with path),
      name: APP_DATABASE_URL    # or safegrd: the remote server holds it for this host
  - id: user-uploads
    type: files
    schedule: "6h"
    roots: ["/var/www/uploads"]

safegrd.example.yaml 是带注释的版本。守护进程启动时会读取配置,因此修改后请运行 safegrd daemon restart。

7. 在执行破坏性命令前创建锁定快照

safegrd guard 会备份一个 surface,等待快照上传并锁定,然后 再运行命令。如果备份失败或快照未锁定,则不会运行命令,guard 会以状态码 3 退出。

safegrd guard --surface app-primary -- psql "$APP_DATABASE_URL" -c 'DROP TABLE sessions'
safegrd guard -- terraform destroy

# The commands a hook treats as destructive, and a check that takes no backup
safegrd guard --list
safegrd guard --matches "npx prisma migrate reset"   # exit 0: it matches

存储在主机自身磁盘上的快照,或 worm_mode: NONE 的存储桶,无法锁定快照, 因此 guard 会拒绝在这些位置运行,除非传入 --allow-unlocked。

年龄不超过 --max-age 的 surface 锁定快照可代替新备份,因此连续运行多个破坏性命令的 Agent 只需备份一次。--check-only 完全不会执行备份;除非存在这样的快照,否则会拒绝运行命令:

safegrd guard --max-age 30m -- psql "$APP_DATABASE_URL" -c 'TRUNCATE sessions'
safegrd guard --max-age 1h --check-only -- terraform destroy

safegrd list --json 会打印所有快照及其锁定日期,供脚本使用。

8. 备份目录树并取回单个文件

文件备份采用增量方式:每月首次运行时会上传所有文件,此后的每次 运行只会上传有更改的数据块。每个文件的所有保留版本都可以搜索,并且可以单独恢复 单个文件。

safegrd backup --files /srv/app --exclude '*.tmp,node_modules/*'

# every kept version of a file, numbered from the oldest
safegrd find etc/nginx/nginx.conf

# one version of one file, or a directory as it was in one snapshot
safegrd restore --path etc/nginx/nginx.conf --version 2 --target-dir ./out
safegrd restore --snapshot snap-20260919-01 --path 'var/www/**' --target-dir ./out

# every pack present and every listing consistent, without restoring anything
safegrd check --all
# a bucket over the S3 API (Supabase Storage, or any S3-compatible store)
safegrd backup --files s3://avatars --source-endpoint https://PROJECT.storage.supabase.co/storage/v1/s3 \
  --source-region eu-central-1 --source-access-key env:S3_KEY --source-secret-key env:S3_SECRET
# and back into the bucket, each object with the content type it had
safegrd restore --snapshot snap-20261012-01 --target s3://avatars --source-endpoint https://PROJECT.storage.supabase.co/storage/v1/s3 \
  --source-region eu-central-1 --source-access-key env:S3_KEY --source-secret-key env:S3_SECRET

--format tar 则会为每次备份保留一个压缩包。锁定的内容、锁定时长以及恢复时会取回的内容,请参阅:safegrd.dev/docs/surfaces/files。


AI Agent(MCP)

safegrd 有两个 MCP 服务。两者都没有删除备份、更改备份位置或获取私钥的工具。

本地服务 safegrd mcp 通过 stdio 在主机上运行,并使用该主机的配置和密钥。它的工具有 status、list、doctor、backup、verify、restore 和 export,每个工具都会运行同名命令。restore 只会写入新目录、空目录或空数据库。

claude mcp add safegrd-local -- safegrd mcp

# a host that runs the container image: mount the volume it enrolled with
claude mcp add safegrd-local -- docker run -i --rm \
  -v safegrd:/home/safegrd/.safegrd ghcr.io/safegrd/cli mcp

远程服务 https://safegrd.dev/mcp 会读取每台主机的备份和 Fire Drill,并在每个套餐中随时请求执行备份或演练。添加时不填写任何请求头,然后在 Claude Code 中运行 /mcp 并选择 Authenticate:在浏览器中登录 SafeGrd 并批准。

claude mcp add --transport http safegrd https://safegrd.dev/mcp

safegrd/agent-plugins 中的 Claude Code 插件会以相同方式添加同一服务器并登录,还提供技能,可在进行高风险更改前创建备份并运行 Fire Drill:

/plugin marketplace add safegrd/agent-plugins
/plugin install safegrd@safegrd

无法登录的客户端(例如 CI)可从控制台的 Tokens 页面获取个人访问令牌,并将其作为 Authorization: Bearer sg_pat_... 发送。

两个服务均列在 MCP Registry 中,名称为 dev.safegrd/safegrd;远程服务也列在 Smithery 上。Cursor 和 VS Code 配置,以及每个工具的参数:safegrd.dev/docs/mcp。


备份内容

  • PostgreSQL,增量备份: 架构来自 pg_dump,行数据则通过二进制 COPY 从同一快照流式传输,因此数组、枚举、外键、视图、触发器和序列位置都能恢复。每次运行只会上传每张表中发生变化的数据块;restore --table 会将所选表载入正在运行的数据库;--change-log 则会跳过自上次运行以来没有写入的表。--format tar 会为每次备份保留一个归档文件。主机上需要安装版本至少与服务器版本相同的 pg_dump。
  • SQLite,增量备份: 通过 SQLite 在线备份在一个读取事务中复制,因此 WAL 中尚未提交的事务也会包含在内,写入操作也能继续进行。副本会保留数据库页面的原位布局,因此每次运行只会上传页面发生变化的数据块。--format tar 会为每次备份保留一个归档文件。主机上无需安装任何软件。
  • MySQL 和 MariaDB: 使用 mysqldump --single-transaction;MongoDB 使用 mongodump --archive,每次备份生成一个归档文件。
  • 目录树,增量备份: 每次运行只会上传发生变化的数据块;每个对象写入时都会被锁定一次;safegrd find 会列出文件的所有保留版本,以供 restore --path --version 使用。
  • IMAP 邮箱: 每封邮件均以 RFC 5322 邮件格式保存,并在每次 Fire Drill 中通过 SHA-256 校验。
  • 锁定存储: 使用合规模式的 S3 Object Lock,或在可能需要解除锁定时使用治理模式。保存在主机本地磁盘上的数据,以及 worm_mode: NONE 的存储桶,都不会锁定备份。
  • Fire Drill: 按计划恢复备份、统计恢复结果,并为每次测试的记录签名。

开发

需要 Go 1.25 或更高版本。直接运行 make(不指定目标)会列出所有目标。

make build      # compile bin/safegrd
make test       # unit and integration tests, race detector
make ci         # the exact gate CI runs: gofmt check, tidy check, vet, race tests
make dist       # cross-compile release archives + checksums into dist/
make fmt tidy   # the developer-facing fixers (these rewrite files; `ci` never does)

CI 会在每次推送和拉取请求时运行 make ci,因此本地运行通过就意味着流水线也会通过。标记 v* 会运行 make dist VERSION=<不含 v 的标签>,并将归档文件和 checksums.txt 发布为 GitHub Release。


许可证

Business Source License 1.1,附带 Additional Use Grant。详见 LICENSE。

简而言之:你可以自由阅读、修改和构建,也可以在任何地方将其用于评估。 任何套餐的 SafeGrd 账户(包括免费套餐)均可用于生产。 无论是否拥有账户,始终允许列出、验证、恢复和导出备份。 每个版本发布四年后将转为 GPL-3.0-or-later。商业许可请联系 [email protected]。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。