Repository navigation
Conversation
… vars Signed-off-by: Бат-Орших <34618353+orshih6@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
Explicitly empty boolean environment variables bypass validation and can start the server with read-only or lockdown protections disabled.
2 open issues
What changed in this PR
Adds boolean environment-value validation to the GitHub MCP Server CLI, addressing the silent disabling of safety settings described in #3747.
Changes:
- Validates boolean settings during startup for
stdio,http, andlist-scopes. - Adds table-driven tests for valid, invalid, and unset environment values.
- Documents accepted boolean spellings and startup errors.
| File | Description |
|---|---|
docs/server-configuration.md |
Documents accepted boolean environment values. |
cmd/github-mcp-server/main.go |
Adds validation to stdio and HTTP startup. |
cmd/github-mcp-server/main_test.go |
Tests read-only and lockdown environment parsing. |
cmd/github-mcp-server/list_scopes.go |
Validates read-only before listing scopes. |
cmd/github-mcp-server/helpers.go |
Defines boolean keys and shared validation logic. |
Review effort: Max (auto)
…ed values Signed-off-by: Бат-Орших <34618353+orshih6@users.noreply.github.com>
|
@copilot good catches, both fixed. An empty bool env var like GITHUB_READ_ONLY= is now rejected at startup. A flag passed explicitly (e.g. --read-only=false) still overrides it, so validateBoolSettings now takes the command's flag set to check that. The test now clears every checked variable up front and restores them at cleanup. It also gained cases for an empty value and for a flag overriding an empty env var. |
SoulmatelynchVFX
left a comment
There was a problem hiding this comment.
Review 草稿 · github/github-mcp-server #3750
- PR:
Reject invalid boolean values for GITHUB_READ_ONLY and other bool env vars(orshih6 · OPEN · 2026-11-09T01:42Z) - 提交方式:
gh pr review 3750 --repo github/github-mcp-server --comment --body-file <正文> - 状态:已备未发,等用户确认
- 说明:本条按 §6.9.6 写,只含可验证信息,不含空 suggestion,不对当前修复作全称判断。
复核依据(读 cmd/github-mcp-server/helpers.go 新增函数 + list_scopes.go 调用点)
- 空值路径:
os.LookupEnv返回 present=true、value="" 时不continue,落到strconv.ParseBool("")→ 返回错误。注释里写明这是有意为之("a present-but-empty variable is rejected too")。 - 容器习惯写法:
docker run -e GITHUB_READ_ONLY ...(不带=value)会把该变量设为空字符串而非未设置;当前 viper 把空值当未设置、read-only 静默关闭,本 PR 之后同样写法会直接 fatal。 - 错误文案:
strconv.ParseBool实际接受1 t T TRUE true True 0 f F FALSE false False,而报错里只列了1, t, true, 0, f, false。
正文
Read validateBoolSettings in cmd/github-mcp-server/helpers.go and the call site in list_scopes.go. Two things I could verify locally, both about the empty-value branch rather than the parsing itself.
The branch that rejects present && value == "" is a behaviour change for container users. docker run -e GITHUB_READ_ONLY ... (no =value) sets the variable to an empty string, not unset, and viper currently treats that as unset so read-only stays off. After this change the same invocation exits with an error instead of starting with read-only disabled. If failing closed is the intent, that is defensible — but it is a startup failure for setups that work today, so it may deserve a line in the release note or an explicit test case (GITHUB_READ_ONLY= with an empty value) so the change is visible.
Second, the error message lists 1, t, true, 0, f, false, while strconv.ParseBool also accepts T, TRUE, True, F, FALSE, False. Someone who writes GITHUB_LOCKDOWN_MODE=True gets no error, but the message implies they should have used lowercase.
I did not check the other boolSettings keys against the actual flag definitions, so I am not claiming the list is complete or that every key is reachable from an env var.
AI-assisted review (Claude); the checks above were run locally against the PR branch.
…he empty-value change Signed-off-by: Бат-Орших <34618353+orshih6@users.noreply.github.com>
|
@SoulmatelynchVFX thanks for checking this. The error message now lists every value ParseBool accepts (1, t, T, true, TRUE, True, 0, f, F, false, FALSE, False). The test now checks that, and it also covers T/True/F/FALSE/False. There's already an explicit empty-value case: |
Signed-off-by: Бат-Орших <34618353+orshih6@users.noreply.github.com>


Boolean settings such as
GITHUB_READ_ONLYandGITHUB_LOCKDOWN_MODEwere read withviper.GetBool. It runs the value throughstrconv.ParseBooland returnsfalseif parsing fails. SoGITHUB_READ_ONLY=yes,on,enabledor a typo liketruquietly left read-only mode off and exposed every write tool. viper also treats an empty variable (GITHUB_READ_ONLY=) as unset, which has the same effect. The--read-only=yesflag form already fails, because pflag parses it strictly.This change adds
validateBoolSettings, which takes the raw viper value for each bool key. When that value is a string (which in practice means it came from the environment), it checks it withstrconv.ParseBool. A variable that is set but empty is rejected too. Both checks are skipped when the matching flag was passed explicitly, because the flag overrides the env var. On failure it returns an error naming the variable, e.g.invalid value "yes" for GITHUB_READ_ONLY: must be a boolean (1, t, T, true, TRUE, True, 0, f, F, false, FALSE, False). The stdio and http commands call it at the start ofRunE, so startup exits non-zero just as it does for a bad flag. It covers read-only, lockdown-mode, insiders, export-translations and enable-command-logging, plus scope-challenge and trust-proxy-headers for http.list-scopeschecks read-only as well.Valid values behave as before, since the check uses the same parser as
GetBool. An unset env var is still false, and an explicit flag still overrides the env var. A note on the accepted values was added to docs/server-configuration.md.Behaviour change (worth a release-note line): an invalid or empty value in any of these bool env vars, not only read-only and lockdown, now stops startup instead of being treated as false. That includes values that used to be accepted silently, such as
GITHUB_INSIDERS=yes, and a variable that is set but empty, such asGITHUB_READ_ONLY=ordocker run -e GITHUB_READ_ONLY=. The docs note says so explicitly.Testing:
TestValidateBoolSettingsFromEnv, coversGITHUB_READ_ONLYandGITHUB_LOCKDOWN_MODE. It checks that1/true/TRUE/True/t/T/0/false/FALSE/False/f/Fparse correctly, that an empty value andyes/on/enabled/trureturn an error listing every accepted value, that an explicit flag overrides an empty env var, and that an unset variable gives false. The test clears every checked variable first, so the environment it runs in doesn't affect the result.go test ./cmd/github-mcp-server/(also run withGITHUB_READ_ONLY=1 GITHUB_INSIDERS=yesset in the outer environment) andscript/lintpass.GITHUB_READ_ONLY=yes ... stdio,GITHUB_READ_ONLY=yes ... list-scopesandGITHUB_READ_ONLY= ... list-scopesexit 1 with the error.GITHUB_READ_ONLY=1works, andGITHUB_READ_ONLY= ... list-scopes --read-only=falsestill runs because the flag wins.Fixes #3747
This change was prepared with an AI coding agent (Claude) and reviewed by me before submitting. I'm happy to make any changes you'd like.