API 服务器配置


Bencher API 服务器在启动时需要一个 JSON 配置。 这个配置可以通过以下三种方式提供:

  • BENCHER_CONFIG 环境变量:该值应设置为 JSON 配置
  • BENCHER_CONFIG_PATH 环境变量:该值应设置为包含 JSON 配置文件的路径
  • /etc/bencher/bencher.json 文件:此位置的文件包含 JSON 配置

如果没有找到配置,则加载默认配置。

示例 JSON 配置:

{
"console": {
"url": "https://bencher.example.com"
},
"security": {
"issuer": "https://api.bencher.example.com",
"secret_key": "UJu7Cpxb-zFaJYqXD-3mDDSDyj-ZvfxZFZs-X58xjxPy"
},
"server": {
"bind_address": "0.0.0.0:6610",
"request_body_max_bytes": 1048576,
"tls": {
"type": "as_file",
"cert_file": "/path/to/cert.pem",
"key_file": "/path/to/key.pem"
}
},
"logging": {
"name": "Bencher API",
"log": {
"stderr_terminal": {
"level": "info"
}
}
},
"database": {
"file": "/var/lib/bencher/data/bencher.db",
"busy_timeout": 5000,
"cache_size": 65536
},
"smtp": {
"hostname": "mailbonobo.com",
"port": 587,
"starttls": true,
"username": "bencher",
"secret": "WM3F2u9cqSNdBPLfy9sJ5kk9",
"from_name": "Bencher",
"from_email": "info@bencher.example.com"
},
"plus": {
"disaster_recovery": {
"replica": {
"scheme": "s3",
"bucket": "my-bucket",
"path": "path/to/replicate",
"access_key_id": "ABC123DoRemMiABC123",
"secret_access_key": "AA3Chr-JSF5sUQqKwayx-FvCfZKsMev-5BqPpcFC3m7"
}
},
"registry": {
"url": "https://registry.bencher.example.com",
"storage": {
"scheme": "s3",
"bucket": "my-bucket",
"path": "registry",
"endpoint": "https://s3.example.com",
"region": "auto",
"access_key_id": "AKIAIOSFODNN7EXAMPLE",
"secret_access_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"chunk_size": 5242880
},
"upload_timeout": 3600,
"max_body_size": 1073741824
},
"runners": {
"heartbeat_timeout": 90,
"job_timeout_grace_period": 60,
"update_base_url": "https://example.com/downloads/"
},
"rate_limiting": {
"window": 86400,
"unclaimed_limit": 255,
"claimed_limit": 65536,
"plus_limit": 1048576,
"public": {
"requests": {
"minute": 1024,
"hour": 4096,
"day": 8192
},
"attempts": {
"minute": 32,
"hour": 64,
"day": 128
},
"runs": {
"minute": 64,
"hour": 128,
"day": 256
}
},
"user": {
"requests": {
"minute": 2048,
"hour": 8192,
"day": 16384
},
"attempts": {
"minute": 2,
"hour": 4,
"day": 8
},
"credentials": {
"minute": 4,
"hour": 8,
"day": 16
},
"organizations": {
"minute": 2,
"hour": 4,
"day": 8
},
"invites": {
"minute": 8,
"hour": 16,
"day": 32
},
"runs": {
"minute": 64,
"hour": 1024,
"day": 4096
}
},
"project": {
"requests": {
"minute": 2048,
"hour": 8192,
"day": 16384
},
"runs": {
"minute": 64,
"hour": 1024,
"day": 4096
}
},
"runner": {
"requests": {
"minute": 16,
"hour": 256,
"day": 4096
}
},
"oci_bandwidth": {
"unclaimed": 1073741824,
"free": 10737418240,
"plus": 107374182400
}
},
"stats": {
"offset": 11242,
"enabled": true
},
"mcp": {
"openai_apps_challenge": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
},
"oauth": {
"issuer": "https://api.bencher.example.com",
"resources": [
"https://mcp.bencher.example.com/mcp",
"https://api.bencher.example.com/mcp"
],
"signing_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASC...\n-----END PRIVATE KEY-----\n"
}
}
}

console

名称 示例 默认值 是否必填 描述
url “https://bencher.example.com” “http://localhost:3000” 是 指定Bencher UI控制台主机的URL。

security

名称 示例 默认值 是否必填 描述
issuer “https://api.bencher.example.com” “bencher.dev” 否 指定JSON Web Token (JWT) 的发行人。警告 改变此值将导致所有先前生成的JWT无法验证。
secret_key “UJu7Cpxb-zFaJYqXD-3mDDSDyj-ZvfxZFZs-X58xjxPy” 随机生成的UUID v4 是 指定用来生成所有令牌以及封存待处理回调的密钥。它应非常安全! 默认值是随机生成的 UUID v4.当记录时,它将以************的形式出现。

server

此部分基于Dropshot服务器配置。

名称 示例 默认值 是否必填 描述
bind_address “0.0.0.0:6610” “0.0.0.0:6610” 是 指定服务器应绑定给定的IP地址和TCP端口。一般来说,服务器可以绑定到多个IP地址和端口,但这还不支持。
request_body_max_bytes 1048576 1048576 是 指定请求体允许的最大字节数。更大的请求将收到一个400错误。
tls.type “as_file” — 否 指定是否以及如何提供TLS证书和密钥信息。有效值包括“as_file”和“as_bytes”。
tls.cert_file “/path/to/cert.pem” — 只有当 tls.type = as_file 时 指定一个PEM文件的路径,该文件包含了服务器用来证明身份的证书链。第一个证书是终端实体证书,剩下的是指向受信任的CA的中间证书。如果指定,服务器只会为TLS连接监听。
tls.key_file “/path/to/key.pem” — 只有当 tls.type = as_file 时 指定一个PEM编码的PKCS #8文件的路径,该文件包含服务器将使用的私钥。如果指定,服务器只会为TLS连接监听。
tls.certs — — 只有当 tls.type = as_bytes 时 和 tls.cert_file 相同,但以证书数据的字节数组形式提供。
tls.key — — 只有当 tls.type = as_bytes 时 和 tls.key_file 相同,但以键数据的字节数组形式提供。

logging

本节基于 Dropshot logging 配置。

名称 例子 默认值 必选项 说明
name “Bencher API” “Bencher API” 是 指定日志记录器的名称。
log.level “info” “info” 是 指定应包含在日志中的日志消息的严重程度。有效值包括 “trace”, “debug”, “info”, “warn”, “error”, 和 “critical”,它们表示日志严重程度的增序。日志将包含指定级别及更严重级别的日志消息。
log.path — — 仅在 log.mode = “file”时 如果 log.mode 为 “file”,此属性决定日志文件的路径。参见 log.if_exists。
log.if_exists — — 仅在 log.mode = “file”时 如果 log.mode 为 “file”,此属性指定当目标日志文件已存在时应怎么办。有效值包括 “append”(将内容添加到现有文件中),“truncate”(将现有文件截断,然后将其视为刚刚创建的文件使用),以及 “fail”(导致服务器立即退出,并报错)。

database

名称 例子 默认值 必选项 说明
file “path/to/database.db” “/var/lib/bencher/data/bencher.db” 是 控制服务器数据库的位置。
busy_timeout 5000 5000 否 指定数据库的忙碌超时时间,以毫秒为单位。防止在锁争用时立即出现SQLITE_BUSY错误。
cache_size 65536 65536 否 指定写入数据库连接的页面缓存大小,以KiB为单位。更大的缓存可以避免在大型报告摄取和删除期间重新读取被逐出的页面。 必须大于0。

smtp

本节指定了SMTP服务配置。整个部分是可选的。如果未指定,所有消息将被发送到logging。

名称 示例 默认值 必需 描述
hostname “mailbonobo.com” — 是 指定SMTP主机名。
port 587 587 否 指定SMTP端口。
insecure_host — false 否 控制SMTP连接是否允许无效的TLS证书。
starttls true true 否 控制SMTP连接是否使用STARTTLS协议。
username “bencher” — 是 指定SMTP主机的用户名。
secret “WM3F2u9cqSNdBPLfy9sJ5kk9” — 是 指定SMTP主机用户名的密码。记录时将显示为************。
from_name “Bencher” — 是 指定在所有电子邮件的发件人部分显示的名称。
from_email “info@bencher.example.com” — 是 指定在所有电子邮件的发件人部分显示的邮箱。

plus

此部分用于介绍由Bencher Plus License覆盖的特性。

plus.github

此部分指定了用于 OAuth2 认证的 GitHub 应用的配置。 服务器上至少有一个组织必须拥有有效的 Bencher Plus 企业 许可证。 整个部分是可选的。 如果未指定,则不会启用与 GitHub 的认证。

名称 示例 默认值 是否必要 描述
client_id Iv1.12864abcd1232048 — 是 为您的 GitHub App 指定 client ID。client ID 与 app ID 不同。您可以在应用的设置页面上找到 client ID。有关导航到 GitHub 应用设置页面的更多信息,请参见 修改 GitHub App 注册.
client_secret 00000abcd12345wxyz123456789abcdefgh0000 — 是 您的 GitHub 应用的client secret。您可以在应用的设置页面上生成 client secret。
app { … } — 否 指定为项目关联的仓库签发 dispatch 令牌的 GitHub App。必须是 client_id 所指定的同一个 GitHub App。该应用需要对仓库内容的读写权限。如果未指定,则任何项目都无法关联仓库。
app.slug my-bencher-app — 是 您的 GitHub App 在其 URL 中的名称,如 https://github.com/apps/my-bencher-app。它指向用户安装该应用的页面。
app.private_key “—–BEGIN RSA PRIVATE KEY—–\n…” — 是 您的 GitHub App 的 PEM 格式私钥。您可以在应用的设置页面上生成私钥。
app.webhook_secret 0123456789abcdef0123456789abcdef — 是 您的 GitHub App 的 webhook 密钥。您可以在应用的设置页面上设置 webhook 密钥。

plus.google

本节指定用于 用于 OAuth2 身份验证的 Google 客户端 的配置。您必须为服务器上的至少一个组织拥有有效的 Bencher Plus 企业版 许可证。整个部分为可选。如果未指定,则不会启用 Google 认证。

名称 示例 默认 必填 描述
client_id 0123456789-abcdefg0112358envs.apps.googleusercontent.com — 是 指定您 Google OAuth2 客户端的客户端 ID。
client_secret GOCSPX-xyz987654321 — 是 用于您 Google OAuth2 客户端的客户端密钥。

plus.disaster_recovery

此部分指定了灾难恢复配置。 Bencher支持连续复制所有数据库更改。

有两种复制scheme:

  • file: 复制到本地文件路径
    • path: 复制路径
  • s3: 复制到任何S3兼容的Blob存储
    • bucket: 存储桶名称
    • path: (可选)存储桶中的路径
    • endpoint: (AWS:可选 | 非AWS:必需)复制端点
    • region: (可选)存储桶区域
    • access_key_id: S3访问密钥
    • secret_access_key: S3密钥

以上两种复制scheme均有以下附加选项:

  • snapshot.interval: (可选)指定创建新快照的频率。这用于减少恢复时间,因为较新的快照将有较少的WAL帧需要应用。保留仍然适用于这些快照。如果未设置快照间隔,则每次执行保留时都会创建新快照。默认情况下,每24小时进行一次保留。
  • snapshot.retention: (可选)快照和WAL文件保留的时间。保留期过后,会创建新的快照并删除旧的。在最旧快照之前存在的WAL文件也将被删除。默认值为24h。
  • validation.interval: (可选)如果指定,Bencher将自动恢复并验证副本上的数据与本地副本是否匹配。默认情况下禁用。启用此选项可能会显著增加运行Bencher的成本,因为大多数云服务会为下载收费。
  • sync_interval: (可选)将帧推送到副本的频率。默认值为1s。增加频率可能显著增加云存储成本。
  • checkpoint.interval: (可选)Litestream执行非阻塞PASSIVE检查点的频率,不受页面数量影响。如果有活跃的读取器或写入器,Litestream将跳过检查点。默认值为1m。
  • checkpoint.min_page_count: (可选)触发非阻塞PASSIVE检查点前的最小WAL页面数(每页约4KB)。如果有活跃的读取器或写入器,Litestream将跳过检查点。默认值为1000(约4MB)。
  • checkpoint.truncate_page_n: (可选)阻塞TRUNCATE检查点的页面数阈值。当达到此阈值时,Litestream会执行阻塞检查点,等待所有读取器和写入器完成,这可能在负载下导致database is locked错误。默认值为0(禁用)。 仅在需要WAL文件大小上限并了解阻塞影响的情况下才设置为非零值。
名称 示例 默认值 是否必需 描述
replica { … } — 是 指定副本对象。
replica.scheme “s3” — 是 指定复制方案。有关所有其他replica键,请参阅上述列表。
snapshot.interval “1h” — 否 创建新快照的频率。减少恢复时间。
snapshot.retention “24h” 24h 否 快照和WAL文件在被替换前保留的时间。
validation.interval “6h” — 否 恢复并验证副本数据与本地副本一致性的频率。默认禁用。
checkpoint.interval “1m” 1m 否 非阻塞PASSIVE检查点的执行频率。如果有活跃的读取器/写入器则跳过。
checkpoint.min_page_count 1000 1000 否 PASSIVE检查点触发前的最小WAL页面数(每页约4KB)。如果有活跃的读取器/写入器则跳过。
checkpoint.truncate_page_n 0 0 否 阻塞TRUNCATE检查点的页面阈值。0为禁用。 非零值可能在负载下导致database is locked。

plus.registry

此部分指定 OCI(Open Container Initiative)注册表存储配置。 Bencher 可以作为符合 OCI 标准的容器/工件注册表运行。

如果未配置此部分,Bencher 将使用本地文件系统存储, 存储在数据库文件旁边的 registry 目录中。 这适用于开发和单实例部署。

对于多实例的生产部署或需要持久性时, 请配置 S3 兼容的存储。

有两种存储 scheme:

  • file:将 OCI 工件存储在本地文件系统中(默认)
    • path:(可选)注册表数据的目录。默认为数据库文件旁边的 registry 目录。
  • s3:将 OCI 工件存储在任何 S3 兼容的 Blob 存储中
    • bucket:存储桶名称
    • path:(可选)存储桶中的键前缀。开头、结尾和重复的斜杠会被移除,因此 registry、registry/ 和 /registry 都存储在 registry 下。
    • endpoint:(AWS:可选 | 非AWS:必需)存储端点
    • region:(可选)存储桶区域。AWS 必需。默认为 auto,这是 S3 兼容存储所期望的值。
    • access_key_id:S3 访问密钥
    • secret_access_key:S3 密钥
    • chunk_size:(可选)上传数据存储之前缓冲的最小块大小(字节)。默认值:5 MB。 HTTP 请求正文以小型网络帧的形式到达(通常为 8 到 64 KB)。如果不进行缓冲,每个帧都会成为一个单独的对象,每层会创建数千个对象。此值也与 S3 分段上传的最小分段大小一致。

请设置存储桶生命周期规则以中止未完成的分段上传。Blob 上传完成过程中崩溃会留下一个未完成的分段上传,服务器不会中止它。

如果您之前配置的 path 以斜杠开头或结尾,请在升级前将现有对象移动到规范化的前缀。path 为 registry/ 时,键存储在 registry//<project>/... 下,现在存储在 registry/<project>/... 下。path 的每个段如果包含 ASCII 控制字符、非 ASCII 字符或 \ {` `^` `} % ` ] " > [ ~ < # | * ? 之一,也会在存储的键中被百分号编码;恰好为 . 或 .. 的段会存储为 %2E 或 %2E%2E。其他所有字符(包括空格、+、=、@ 和 :)都按原样存储,因此 team#1 变为 team%231,而 team+1 仍为 team+1。存储在现在会被编码的前缀下的数据也需要同样的迁移。在移动任何数据之前,请列出存储桶中实际存储的键,并与新的前缀进行比较。

名称 示例 默认值 必需 描述
url “https://registry.bencher.example.com” “http://localhost:6610” 否 API 服务器的外部可达 URL,用于 OCI 注册表访问。
storage { … } — 否 指定注册表存储后端。省略时使用本地文件。
storage.scheme “s3” — 是 指定存储 scheme。有关所有其他 storage 键,请参见上面的列表。
upload_timeout 3600 3600 否 上传会话超时时间(秒)。过期上传在启动新上传时被清理。
max_body_size 1073741824 1073741824 否 Blob 和清单上传的最大正文大小(字节)。超过此限制的请求将被拒绝并返回 413 Payload Too Large。默认值:1 GiB。

plus.runners

此部分配置用于裸机基准测试执行的运行器系统。 运行器是服务器范围的代理,负责认领和执行基准测试作业。

如果未配置此部分,Bencher 将使用默认值。

名称 示例 默认值 必需 描述
heartbeat_timeout 90 90 否 在没有心跳的情况下将作业标记为未知之前的时间(秒)。
job_timeout_grace_period 60 60 否 超出作业配置的超时时间后服务器取消作业之前的额外时间(秒)。
update_base_url https://example.com/downloads/ GitHub Releases (stable), download.bencher.dev (canary) 否 运行器自更新下载的基础 URL。设置后,它会同时替换 stable 通道和 canary 通道的默认基础 URL。

plus.rate_limiting

本节指定 API 服务器的速率限制。 整节内容是可选的。 如果未指定,将使用列出的默认值。

为防止创建unclaimed项目,请将unclaimed_limit设置为0。

名称 示例 默认值 是否必需 描述
window 86400 86400 否 指定以秒为单位的速率限制窗口。默认设置为一天。
unclaimed_limit 255 255 否 控制unclaimed项目的速率限制。为了防止创建unclaimed项目,请将此值设置为0。
claimed_limit 65536 65536 否 控制claimed项目的速率限制。
plus_limit 1048576 1048576 否 控制拥有 Bencher Plus 计划的组织的指标速率限制。

public

public速率限制器按IP地址应用于未认证的请求。 每个子字段包含minute、hour和day限制。 整节内容是可选的。 如果未指定,将使用列出的默认值。

名称 示例 默认值 是否必需 描述
requests { … } — 否 指定每个IP地址的请求速率限制。
requests.minute 1024 1024 否 每个IP地址每分钟最大请求数。
requests.hour 4096 4096 否 每个IP地址每小时最大请求数。
requests.day 8192 8192 否 每个IP地址每天最大请求数。
attempts { … } — 否 指定每个IP地址的认证尝试速率限制。
attempts.minute 32 32 否 每个IP地址每分钟最大认证尝试次数。
attempts.hour 64 64 否 每个IP地址每小时最大认证尝试次数。
attempts.day 128 128 否 每个IP地址每天最大认证尝试次数。
runs { … } — 否 指定未认领项目的每个IP地址基准测试运行速率限制。
runs.minute 64 64 否 每个IP地址每分钟最大基准测试运行数。
runs.hour 128 128 否 每个IP地址每小时最大基准测试运行数。
runs.day 256 256 否 每个IP地址每天最大基准测试运行数。

user

user速率限制器按认证用户应用。 每个子字段包含minute、hour和day限制。 整节内容是可选的。 如果未指定,将使用列出的默认值。

名称 示例 默认值 是否必需 描述
requests { … } — 否 指定每个用户的请求速率限制。
requests.minute 2048 2048 否 每个用户每分钟最大请求数。
requests.hour 8192 8192 否 每个用户每小时最大请求数。
requests.day 16384 16384 否 每个用户每天最大请求数。
attempts { … } — 否 指定每个用户的认证尝试速率限制。
attempts.minute 2 2 否 每个用户每分钟最大认证尝试次数。
attempts.hour 4 4 否 每个用户每小时最大认证尝试次数。
attempts.day 8 8 否 每个用户每天最大认证尝试次数。
credentials { … } — 否 指定每个用户的凭证创建速率限制。
credentials.minute 4 4 否 每个用户每分钟最大凭证创建数。
credentials.hour 8 8 否 每个用户每小时最大凭证创建数。
credentials.day 16 16 否 每个用户每天最大凭证创建数。
organizations { … } — 否 指定每个用户的组织创建速率限制。
organizations.minute 2 2 否 每个用户每分钟最大组织创建数。
organizations.hour 4 4 否 每个用户每小时最大组织创建数。
organizations.day 8 8 否 每个用户每天最大组织创建数。
invites { … } — 否 指定每个用户的邀请速率限制。
invites.minute 8 8 否 每个用户每分钟最大邀请数。
invites.hour 16 16 否 每个用户每小时最大邀请数。
invites.day 32 32 否 每个用户每天最大邀请数。
runs { … } — 否 指定每个用户的基准测试运行速率限制。
runs.minute 64 64 否 每个用户每分钟最大基准测试运行数。
runs.hour 1024 1024 否 每个用户每小时最大基准测试运行数。
runs.day 4096 4096 否 每个用户每天最大基准测试运行数。

project

project速率限制器按项目应用。 每个子字段包含minute、hour和day限制。 整节内容是可选的。 如果未指定,将使用列出的默认值。

名称 示例 默认值 是否必需 描述
requests { … } — 否 指定每个项目的请求速率限制。
requests.minute 2048 2048 否 每个项目每分钟最大请求数。
requests.hour 8192 8192 否 每个项目每小时最大请求数。
requests.day 16384 16384 否 每个项目每天最大请求数。
runs { … } — 否 指定每个项目的基准测试运行速率限制。
runs.minute 64 64 否 每个项目每分钟最大基准测试运行数。
runs.hour 1024 1024 否 每个项目每小时最大基准测试运行数。
runs.day 4096 4096 否 每个项目每天最大基准测试运行数。

runner

runner速率限制器按运行器应用。 每个子字段包含minute、hour和day限制。 整节内容是可选的。 如果未指定,将使用列出的默认值。

名称 示例 默认值 是否必需 描述
requests { … } — 否 指定每个运行器的请求速率限制。
requests.minute 16 16 否 每个运行器每分钟最大请求数。
requests.hour 256 256 否 每个运行器每小时最大请求数。
requests.day 4096 4096 否 每个运行器每天最大请求数。

oci_bandwidth

oci_bandwidth指定每个组织层级的每日OCI注册表带宽限制。 整节内容是可选的。 如果未指定,将使用列出的默认值。

名称 示例 默认值 是否必需 描述
unclaimed 1073741824 1073741824 否 未认领组织(0个成员)每天的最大字节数。默认为1 GiB。
free 10737418240 10737418240 否 免费(已认领,无付费计划)组织每天的最大字节数。默认为10 GiB。
plus 107374182400 107374182400 否 Plus(Pro/Enterprise)组织每天的最大字节数。默认为100 GiB。

plus.stats

该部分指定是否以及何时收集服务器统计信息。 整个部分是可选的。 如果未指定,将使用列出的默认值。 也就是说,服务器统计信息是默认启用的。 设置enabled为false以禁用服务器统计。

名称 示例 默认 是否必需 描述
offset 11242 11242 否 指定从午夜开始以秒为单位的偏移量以收集服务器统计信息。默认情况下,它在03:07:22 UTC进行运行。
enabled true true 否 控制是否收集服务器统计信息。设置为false以选择不收集。

plus.mcp

此部分配置 Bencher MCP 服务器。 整个部分是可选的。

名称 示例 默认值 必需 描述
openai_apps_challenge a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6 — 否 当您提交使用此 MCP 服务器的应用时,OpenAI 签发的域名验证令牌。API 服务器会在 /.well-known/openai-apps-challenge 以纯文本形式提供该令牌。如果未指定,该路由返回 404 Not Found。

plus.oauth

此部分让 ChatGPT、claude.ai 和 Claude Code 等 MCP 客户端可以通过 OAuth 登录 Bencher MCP。 API 服务器会成为它们的 OAuth 授权服务器,用户在位于 console.url 的 Bencher Console 上批准每个应用。 整个部分是可选的。 如果未指定,则 OAuth 处于关闭状态:其端点返回 404 Not Found,并且 Bencher MCP 只接受 API 密钥和匿名请求。

名称 示例 默认值 必需 描述
issuer “https://api.bencher.example.com” — 是 此 API 服务器的公开源(origin),应用在这里找到它的 OAuth 端点:https,或仅对 localhost 等回环主机使用 http。它必须是不带路径的源,否则服务器将无法启动。警告 resources 中未列出任何 URL 时,默认资源随此值变化,因此更改此值会断开通过旧默认资源登录的应用,直到恢复原值;resources 中列出了 URL 时,只要旧的源仍能到达此服务器,更改此值就不会断开任何连接。
resources ["https://mcp.bencher.example.com/mcp", "https://api.bencher.example.com/mcp"] [<issuer>/mcp] 否 应用登录的、此服务器 MCP 端点的 URL,规范 URL 排在第一位:https,或仅对回环主机使用 http。未指明任何 URL 的应用会得到第一个。移除某个 URL 会断开通过它登录的应用,直到再次将其列出;没有剩余 URL 时,提供默认资源。
clients [{ … }] — 否 唯一允许登录的应用。移除某个应用会断开该应用,直到再次将其列出。列出的应用会在授权同意页面上标记为已验证。如果未指定,只要 API 服务器能从应用的客户端 ID 获取有效的客户端元数据文档,任何应用都可以请求登录。
clients.id “https://app.example.com/oauth/client.json” — 是 应用的客户端 ID:其客户端元数据文档的 https URL。
clients.metadata { … } — 否 应用的客户端元数据文档,用于代替从 id 获取,例如在无法访问互联网的服务器上。它必须是 client_id 等于 id 的有效客户端元数据文档,否则服务器将无法启动。
signing_key "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n" — 否 用于签署 ID 令牌的 RSA 私钥,至少 2048 位,PEM 格式(PKCS #1 或 PKCS #8)。它会开启 OpenID Connect:openid、email 和 profile 作用域、ID 令牌,以及 UserInfo、JWKS 和发现端点。如果未指定,则 OpenID Connect 处于关闭状态。如果它不是有效的密钥,服务器将无法启动。它应非常安全! 当记录时,它将以************的形式出现。

JSON 字符串不能包含换行符,因此请将 signing_key 中的每个换行写作 \n。 例如,生成一个密钥并将其输出为 JSON 字符串,而不写入文件:

Terminal window
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 | jq -Rs .

要轮换签名密钥,替换它即可。这不会断开任何应用的连接。

API 服务器在 issuer 的根路径下提供其 OAuth 端点和元数据。 如果反向代理在路径前缀下提供 API 服务器,例如 https://bencher.example.com/api, 请将 issuer 设置为源(https://bencher.example.com),并在 resources 中列出 MCP 端点的完整 URL(https://bencher.example.com/api/mcp)。 此时,代理必须将源上的 /oauth/、/.well-known/oauth-authorization-server 和 /.well-known/openid-configuration 路由到 API 服务器上的相同路径, 并将每个资源的元数据路径(此处为 /.well-known/oauth-protected-resource/api/mcp)路由到 API 服务器上的 /.well-known/oauth-protected-resource/mcp。 当有多个资源时,代理还必须原样传递 Host 请求头,因为 API 服务器根据它选择要公布的资源。



Published: Fri, October 27, 2023 at 8:40:00 AM UTC | Last Updated: Wed, November 4, 2026 at 11:28:40 PM UTC