Skip to content

Commit b20d651

Browse files
committed
mcp(fix[pane_tools]): document capture_pane truncation marker for agents
When ``capture_pane`` truncates, the returned string is prefixed with a literal ``[... truncated K lines ...]`` first line so the caller can detect the cap. This is documented in the function docstring at ``pane_tools/io.py:174-178``, but FastMCP only surfaces the ``description=`` override registered at ``pane_tools/__init__.py:83-95``, not the docstring — and the override only said "tail-preserving truncation at max_lines, default 500". Agents reading the description had no signal that the first line of a truncated response is a marker rather than terminal content, and could mishandle the output. Extends the override to name the marker and tell the agent it's a literal prefix line to skip when parsing. Also surfaces the ``max_lines=None`` opt-out. Test: adds a row to ``test_tool_description_includes`` asserting ``capture_pane``'s description contains ``"truncated"``. The contract suite already pinned ``snapshot_pane`` / ``wait_for_text`` / ``search_panes`` cross-references; this extends the same drift guard to the truncation behavior.
1 parent d14d48f commit b20d651

2 files changed

Lines changed: 16 additions & 7 deletions

File tree

src/libtmux_mcp/tools/pane_tools/__init__.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,17 @@ def register(mcp: FastMCP) -> None:
8585
annotations=ANNOTATIONS_RO,
8686
tags={TAG_READONLY},
8787
description=(
88-
"Capture the visible contents of a tmux pane (tail-preserving "
89-
"truncation at max_lines, default 500). For pane content + "
90-
"cursor + mode + scroll state in one call, use snapshot_pane. "
91-
"For 'send_keys then wait for output' flows, use wait_for_text "
92-
"or wait_for_content_change instead of a capture_pane retry "
93-
"loop — server-side blocking is dramatically cheaper in agent "
94-
"turns. To find text across many panes, use search_panes."
88+
"Capture the visible contents of a tmux pane. Output is "
89+
"tail-preserving truncated at max_lines (default 500); when "
90+
"truncation occurs, the first line of the returned string is a "
91+
"literal '[... truncated K lines ...]' marker — skip it when "
92+
"parsing terminal content. Pass max_lines=None to disable "
93+
"truncation. For pane content + cursor + mode + scroll state in "
94+
"one call, use snapshot_pane. For 'send_keys then wait for "
95+
"output' flows, use wait_for_text or wait_for_content_change "
96+
"instead of a capture_pane retry loop — server-side blocking "
97+
"is dramatically cheaper in agent turns. To find text across "
98+
"many panes, use search_panes."
9599
),
96100
)(capture_pane)
97101
mcp.tool(

tests/test_server.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,11 @@ def test_registered_tools_accept_socket_name() -> None:
402402
("capture_pane", "snapshot_pane"),
403403
("capture_pane", "wait_for_text"),
404404
("capture_pane", "search_panes"),
405+
# Truncation marker — agents need to know the first line of a
406+
# truncated capture is a literal '[... truncated K lines ...]'
407+
# header, not terminal content. Without this in the description,
408+
# an agent might treat the marker as the most recent output.
409+
("capture_pane", "truncated"),
405410
("show_hooks", "tmux config file"),
406411
("load_buffer", "list_buffers"),
407412
("load_buffer", "clipboard history"),

0 commit comments

Comments
 (0)