flywheel-relay 0.3.0
Write, exec and the working root for the MCP servers move from tool arguments to
launch configuration. This changes what existing MCP calls and setups do, so it
is a minor release rather than a patch. Relay is pre-1.0, where a breaking change
takes the minor number. The breaks:
- A client that sends
allow_write: trueorallow_exec: trueto a server
started without that grant now runs with it off. - A run's
rootmust resolve inside the server's launch root. A call that names
any other directory is refused withROOT_NOT_GRANTED. checkand the onlinecodexandclaudeCLI tiers need exec.- The remote entrypoint no longer reads
RELAY_ALLOW_WRITE,RELAY_ALLOW_EXEC,
RELAY_ALLOW_REMOTE_EXECorRELAY_MCP_ROOTfrom its.envfile. In 0.2.5 a
RELAY_ALLOW_REMOTE_EXECline there was honored; set it in the environment
that starts the server instead. RELAY_ALLOW_REMOTE_EXECacceptsonandoff, and an unrecognized value
now stops the remote server instead of reading as off.
An omitted allow_write or allow_exec still means off, as in 0.2.5.
Source version metadata is not release availability proof; release availability
is established only by the accepted Git tag, uploaded GitHub Release assets, and
matching hash readback. Do not publish or recommend the bare PyPI name
relay-agent; that public namespace belongs to an unrelated project and is not
the HarperZ9 Relay distribution.
Changed
relay --mcpandpython -m relay.local_mcptake write and exec from their
launch:--allow-writeand--allow-exec, orRELAY_ALLOW_WRITEand
RELAY_ALLOW_EXEC. Both are off by default. The launch root comes from
--rootorRELAY_MCP_ROOTand defaults to the working directory. An
unrecognized value or a root that is not a directory stops the server at
launch, including a direct call toserve(), which now returns 2 with a
message instead of raising.- A run gets what it asks for and the launch granted, both.
allow_write: true
andallow_exec: trueask; an omitted argument asks for nothing. Asking for
exec also asks for write, andallow_write: falseturns exec off. - A run's
rootresolves under the launch root, and links are followed before
the check, so neither..nor a link steps outside it. - An MCP run's file tools never read the server's env file (
RELAY_ENV_FILE,
default.env), and never write it, the run store (RELAY_RUN_ROOT), the
session store (RELAY_SESSION_DIR) or anything under a.gitdirectory. On
Windows they refuse a name ending in a dot or a space, or naming a stream,
since it opens another spelling of a file. checkruns a shell outside the tool gate, so an MCP run that sets it needs
exec and is refused withEXEC_NOT_GRANTEDotherwise. Before this release a
caller could reach a shell throughcheckwith exec off.- The online
codexandclaudeCLI tiers start an agent with its own shell.
Without exec,local_agent_chat,local_agent_healthand auto routing leave
them out, and naming one is refused withEXEC_NOT_GRANTED. - On the remote surface, exec needs both
RELAY_ALLOW_EXECand
RELAY_ALLOW_REMOTE_EXEC, and write needsRELAY_ALLOW_WRITEon its own:
RELAY_ALLOW_EXECalone grants the phone nothing. The server configures only
what the surface allows, so its banner andrelay.statusreport what runs
get, and it still refuses exec per request as a second layer. - The remote entrypoint reads the grant variables from its process environment
only, because a run allowed to write could otherwise edit.envand give
itself exec on the next restart. It names any such line it finds at startup,
and the remote readout lists them asenv_file_ignored. .envvalues may carry an inline comment after whitespace (KEY=value # note).
Before this release the comment became part of the value, so the shipped
.env.examplefailed to start as documented.- The request binding is
relay.mcp-run-request/v2. It adds
granted_allow_write,granted_allow_exec,granted_root,
requested_root,grant_shortfall,remote_exec_refusedandprotected,
and reportsrequested_allow_writeandrequested_allow_execasnull
when omitted. relay.statusandrelay.doctorreport the launch grants and root. The
remote readout reports the grants the surface would configure as
start_grants, and addsremote_exec_in_effectnext to
remote_exec_allowed.
Limits
- The shell is not path-confined: with exec granted,
run,test_cmdand
checkstart in root and can reach any path the server's user can. - Write is a route to code execution. A file written under the root runs the
next time something executes it there, such as a build script, a test, or a
shell profile when the root is a home directory. Launch the server over a
workspace its callers may edit. - Background runs keep the gate and root they started with. Changing the grants
needs a server restart.
Assets
The wheel and sdist attached here are the exact files published to PyPI by the release workflow for this tag (run 36256084495). SHA256SUMS.txt lists their SHA-256 digests; verify before installing, as docs/GITHUB-ONLY-INSTALL.md describes. PyPI also carries PEP 740 attestations for both files.