[KongchangAI]
· 2 min read· 1,207 words

Vercel Sandbox Adds stdin Support: Opening Interactive Command Channels for AI Agents

Vercel Sandbox Adds stdin Support: Opening Interactive Command Channels for AI Agents

Vercel Sandbox supports writing stdin to running commands, enabling two-way interaction with long-running processes.

Vercel Sandbox has added standard input support for running commands, upgrading the sandbox from a batch container for one-off scripts to a session environment capable of two-way conversation with long-running processes. The article covers TypeScript SDK usage with stdin: true, detached: true, writeStdin(), closeStdin(), and wait(), as well as the Python SDK path using subprocess.PIPE, server.stdin.send(), and communicate(), noting that stdin can also bind to a Node.js readable stream or be passed at once via input. Typical scenarios include stdio MCP servers, LSP processes, and interactive CLIs, enabling Agents to maintain multi-turn sessions. It also highlights process lifecycle management and message boundaries.

Vercel Sandbox has recently filled in a key gap: running commands can now receive data via standard input (stdin). This means the sandbox is no longer just a "batch container" for executing one-off scripts—it's beginning to support two-way conversation with long-running processes.

rss source: Vercel Sandbox commands now support stdin

From One-Way Execution to Two-Way Interaction

Sandbox models in the past were mostly designed around "execute command—return result": input was provided once at startup and could not be injected during the run. By opening stdin to running commands, Vercel directly changes the boundaries of what scenarios are supported: any CLI program that relies on interactive input can now complete its full workflow inside the sandbox.

The officially highlighted typical use case is stdio MCP servers, such as agent-browser. MCP servers usually exist as child processes and exchange JSON-RPC messages with the host via standard input/output. Without stdin support, such servers could only be started, not actually conversed with; now an Agent can continuously send requests to them inside the sandbox and read responses.

In the context of stdio MCP servers, MCP stands for Model Context Protocol, an open protocol proposed by Anthropic for letting AI applications (hosts) invoke external tools, data sources, and prompt templates in a standardized way.

When using stdio transport, an MCP server runs as a child process launched by the host, and the two parties exchange JSON-RPC 2.0 messages over stdin/stdout: the host writes requests to the child process, and the child process writes results or notifications back on standard output. This transport is simple to deploy and requires no network ports, but it strongly depends on the host being able to continuously write data to the running process—which is exactly why the sandbox could not truly drive MCP servers before, when stdin was missing.

Usage in the TypeScript SDK

In the TypeScript SDK, you need to set both stdin: true and detached: true in runCommand()—the former opens the input channel, and the latter lets the command run in the background to avoid blocking subsequent operations. Then write data via writeStdin(), end input with closeStdin(), and finally call wait() to wait for the process to exit and read stdout.

The official example uses cat to demonstrate the full loop: write hello, close stdin, wait for completion, and the final stdout output is also hello. Although small, this example covers the three key actions: writing, closing, and collecting output.

Besides a boolean value, stdin can also be bound directly to a Node.js readable stream (such as process.stdin). The SDK forwards data from the stream and automatically closes the command's standard input when the stream ends. For scenarios that need to pipe local input into the sandbox, this saves you from writing relay logic by hand.

The purpose of detached: true is to let the command run in detached mode in the sandbox background: after calling runCommand(), a process handle is returned immediately instead of blocking until the command finishes. For interactive scenarios, this step is almost mandatory, because the process often waits for external input before producing output. If you wait synchronously, the caller gets stuck in a deadlock between "waiting for it to exit" and "sending it data." With detached running, developers can hold the handle, call writeStdin() and read stdout at any time, and finally use wait() to uniformly collect the exit status and remaining output.

Usage in the Python SDK

The Python side takes a path closer to subprocess: pass stdin=subprocess.PIPE when calling create_process(), then call server.stdin.send() to send bytes. The example writes ping\n to cat and reads one line of output, then calls communicate() to close stdin, collect remaining output, and wait for the process to exit.

If the command does not need multiple rounds of interaction and can consume all input at once, you can pass input directly to run_process() without going through the PIPE flow. Both approaches coexist, accommodating both interactive and batch-processing needs.

subprocess.PIPE is a special constant in Python's standard library subprocess that indicates "create a pipe." After passing stdin=subprocess.PIPE, the child process's standard input no longer inherits from the parent process but connects to a pipe controlled by the parent, and the parent can write bytes through the stdin attribute of the returned object; similarly, stdout=PIPE lets the parent read the child process's output. The Vercel Python SDK follows this convention, keeping the interaction style of processes inside the sandbox consistent with local subprocess programming habits and reducing migration costs.

Significance for the Agent Toolchain

The value of this capability goes beyond "one more parameter." When Agents run tools in the sandbox, common needs include communicating with Language Server Protocol (LSP) processes, driving interactive CLIs that require step-by-step confirmation, and maintaining MCP sessions. What these scenarios share is that the process lifetime is longer than a single request, and stdin/stdout must be used to maintain the session.

stdin support brings the sandbox closer to a "session environment" rather than just an "execution environment." Combined with detached running mode, an Agent can maintain multiple interactive processes in parallel, writing and reading on demand, without having to restart the process for each step of interaction.

Points to Note When Using It

Interactive processes introduce lifecycle management issues: forgetting to call closeStdin() or communicate() may cause processes to hang and consume sandbox resources. In addition, stream-based input requires proper handling of end signals; otherwise, the command may wait for input forever and never exit. For protocols that require strict ordering (such as JSON-RPC), the writer also needs to ensure message boundaries itself—the SDK only forwards bytes.

These constraints are not complicated, but they mean developers must incorporate "process orchestration" into their designs rather than just stringing together a command. For teams building Agent applications, this is a necessary shift in mindset.

The reason closeStdin() and communicate() are critical is that pipes have "end only when EOF is read" semantics: many CLI programs keep waiting for more data until standard input is closed. If the parent process neither writes nor closes, the child process will hang indefinitely. Protocols based on messages such as JSON-RPC do not themselves carry framing information; pipes guarantee only byte order, not message boundaries. Therefore, the writer must agree on a delimiter (such as line separation or length prefixing), otherwise the receiver may concatenate two messages and fail to parse them.

One-line Summary

Vercel Sandbox supports writing stdin to running commands, enabling two-way interaction with long-running processes.

Paragraph Summary

Vercel Sandbox has added standard input support for running commands, upgrading the sandbox from a "batch container" that can only execute one-off scripts to a session environment capable of two-way conversation with long-running processes. The article explains how to use stdin: true together with detached: true, writeStdin(), closeStdin(), and wait() in the TypeScript SDK, as well as the implementation path in the Python SDK based on subprocess.PIPE, server.stdin.send(), and communicate(). It also notes that stdin can be bound directly to a Node.js readable stream or passed all at once via the input parameter. Typical scenarios include stdio MCP servers, LSP processes, and interactive CLIs, allowing Agents to maintain multi-turn sessions instead of restarting processes at every step. The article also reminds readers about process lifecycle management and message boundaries.

#Vercel Sandbox#stdin#AI Agent#MCP server#TypeScript SDK#Python SDK
Share:

Related articles