Skip to content

fix: respect ROOTLY_MCP_ENABLE_WRITE_TOOLS=false on the CLI path#150

Open
kstlouis wants to merge 2 commits into
rootlyhq:mainfrom
kstlouis:fix/readonly-env-var-ignored-on-cli
Open

fix: respect ROOTLY_MCP_ENABLE_WRITE_TOOLS=false on the CLI path#150
kstlouis wants to merge 2 commits into
rootlyhq:mainfrom
kstlouis:fix/readonly-env-var-ignored-on-cli

Conversation

@kstlouis

Copy link
Copy Markdown

Prepared with the help of Claude Code.

Fixes #149.

Problem

On the console-script / python -m rootly_mcp_server path, setting ROOTLY_MCP_ENABLE_WRITE_TOOLS=false does not restrict the server to read-only — all write tools (createIncident, updateSchedule, createTeam, …) stay exposed. The README documents the env var as equivalent to the --no-enable-write-tools flag, so a user following it believes they're read-only while ~82 write tools remain callable with a full-privilege token.

Cause

In main():

enable_write_tools = args.enable_write_tools or write_tools_enabled_from_env(default=hosted_mode)

--no-enable-write-tools is action="store_false", default=True, so when the flag is absent args.enable_write_tools is True and True or <env> short-circuits — the env var on the right is never consulted.

Fix

  • Change the flag's default to None so "flag absent" is distinguishable from "flag passed → False".
  • Resolve as: explicit flag wins; otherwise fall back to write_tools_enabled_from_env(default=True) (preserves full-access-by-default and matches get_server()).

Behavior after the fix:

Flag ROOTLY_MCP_ENABLE_WRITE_TOOLS Result
absent unset write-enabled (unchanged default)
absent false read-only (now respected)
absent true write-enabled
--no-enable-write-tools any / unset read-only (explicit flag wins)

Tests

Added 4 regression tests in tests/unit/test_main_transport.py driving main() through its --list-tools early-return and asserting the enable_write_tools kwarg: env=false without flag, flag-over-env=true, default, and env=true.

ruff check    -> All checks passed!
pyright       -> 0 errors, 0 warnings
pytest tests/unit -> 501 passed

No README change is needed — the fix makes the existing documented behavior correct.

kstlouis and others added 2 commits June 29, 2026 16:25
The console-script / `python -m` entry point resolved write-tool gating as
`args.enable_write_tools or write_tools_enabled_from_env(...)`. Because
--no-enable-write-tools is `store_false` with `default=True`, the `or`
short-circuits and ROOTLY_MCP_ENABLE_WRITE_TOOLS=false is ignored whenever the
flag is absent, leaving all write tools exposed despite the documented
read-only setting.

Default the flag to None so an absent flag falls back to the env var
(defaulting to write-enabled, matching get_server()); an explicit
--no-enable-write-tools still wins. Add regression tests for env=false,
flag-over-env, and the default.

Fixes rootlyhq#149
Extract the flag-wins-else-env-else-default resolution into a single
resolve_write_tools_enabled() helper so main() and get_server() can't
drift apart (the drift is what caused the original env-var bug). Add
direct unit tests for the resolver plus flag-without-env and
hosted+env=false regression cases, and flatten the test helper's nested
with-blocks into a parenthesized context group.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: ROOTLY_MCP_ENABLE_WRITE_TOOLS=false does not enforce read-only on the CLI / python -m path — write tools stay exposed

2 participants