send_input
Send text input to terminal surfaces in the cmuxlayer MCP server. For reliable command execution, send text first, then use a separate send_key call for the return key.
Instructions
Send text input to a terminal surface. When sending commands to another Claude session, press_enter can be unreliable — for critical inputs, use send_input without press_enter, then call send_key with key 'return' separately.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| surface | Yes | Target surface ref | |
| text | Yes | Text to send | |
| workspace | No | Target workspace ref | |
| press_enter | No | Press enter after sending text. For reliability with interactive programs, send text first, then use a separate send_key 'return' call. | |
| rename_to_task | No | Rename tab suffix to this task name |
Implementation Reference
- src/server.ts:289-319 (handler)The handler function for the send_input tool, which sends text to a terminal, optionally presses enter, and renames a tab.
async (args) => { try { await client.send(args.surface, args.text, { workspace: args.workspace, }); if (args.press_enter) { // Small delay to let the terminal process the text input before // sending the return key. Without this, the enter keypress can // arrive before the text is fully inserted into the terminal's // input buffer, causing the enter to be swallowed. await new Promise((resolve) => setTimeout(resolve, 50)); await client.sendKey(args.surface, "return", { workspace: args.workspace, }); } if (args.rename_to_task) { const surfaces = await client.listPaneSurfaces({ workspace: args.workspace, }); const surface = surfaces.surfaces.find((s) => s.ref === args.surface); const currentTitle = surface?.title ?? ""; const newTitle = replaceTaskSuffix(currentTitle, args.rename_to_task); await client.renameTab(args.surface, newTitle, { workspace: args.workspace, }); } return ok({ surface: args.surface, applied: "send_input" }); } catch (e) { return err(e); } }, - src/server.ts:269-315 (registration)Registration of the send_input tool using the server.tool method, including its schema definition.
// 3. send_input server.tool( "send_input", "Send text input to a terminal surface. When sending commands to another Claude session, press_enter can be unreliable — for critical inputs, use send_input without press_enter, then call send_key with key 'return' separately.", { surface: z.string().describe("Target surface ref"), text: z.string().describe("Text to send"), workspace: z.string().optional().describe("Target workspace ref"), press_enter: z .boolean() .optional() .default(false) .describe( "Press enter after sending text. For reliability with interactive programs, send text first, then use a separate send_key 'return' call.", ), rename_to_task: z .string() .optional() .describe("Rename tab suffix to this task name"), }, async (args) => { try { await client.send(args.surface, args.text, { workspace: args.workspace, }); if (args.press_enter) { // Small delay to let the terminal process the text input before // sending the return key. Without this, the enter keypress can // arrive before the text is fully inserted into the terminal's // input buffer, causing the enter to be swallowed. await new Promise((resolve) => setTimeout(resolve, 50)); await client.sendKey(args.surface, "return", { workspace: args.workspace, }); } if (args.rename_to_task) { const surfaces = await client.listPaneSurfaces({ workspace: args.workspace, }); const surface = surfaces.surfaces.find((s) => s.ref === args.surface); const currentTitle = surface?.title ?? ""; const newTitle = replaceTaskSuffix(currentTitle, args.rename_to_task); await client.renameTab(args.surface, newTitle, { workspace: args.workspace, }); } return ok({ surface: args.surface, applied: "send_input" });