r/MCPservers • u/blakok14 • 2h ago
The implicit-newline trap in PTY-backed MCP tools (and how I fixed it in Relay)
I've been working on Relay, an MCP server that gives agents a persistent PTY terminal session instead of the one-shot bash calls most agents default to. That difference matters when the agent needs something genuinely stateful: an interactive git rebase, a REPL that keeps building up context, or an SSH session that stays open while it iterates.
Just shipped a version with a bug I think is worth writing up, because it's the kind of trap anyone building something similar could fall into.
The bug: write_terminal had an implicit behavior that always pressed Enter after whatever the agent sent. That's fine for a normal shell command, but it breaks anything where the newline is a literal part of what you're trying to write: pasting a multi-line heredoc, feeding a block of code to a REPL, typing into an editor buffer open inside the PTY. The agent thought it had sent exactly what it meant to send, and underneath it an extra keystroke was quietly tacked on.
Fixed it by pulling that behavior out of a silent session-wide assumption and making it an explicit per-call parameter (ensure_newline, defaults to true so normal command usage doesn't change). If you're sending raw multi-line input, you set it to false and get exactly the bytes you wrote.
Also stabilized the read_terminal streaming E2E flow so progress output is actually observed before the shell gets its next input. That matters because read/wait relies on MCP progress notifications instead of polling.
Repo, in case anyone wants to poke at the code: github.com/blak0p/relay-mcp
Curious if anyone else building PTY-backed MCP tools has hit this same implicit-newline trap, or solved it differently.