TURA 프로젝트에서 영감 받음
핵심 아이디어는 rg, find, sed, git, cargo test 같은 shell command 호출을 개별 단위가 아닌 묶음으로 처리하게 해서 잦은 도구호출로 인한 토큰을 아끼자는 것이다.
TURA의 TUI가 멋지긴 한데 당장 필요한 건 토큰을 아끼는 기능이므로 핵심 기능인 `command-run`을 MCP로 구현했다. Kontexus-MCP 쪽에 구겨넣지 않고 단독 MCP서버로 만듦. Runtime이 없으니 CLAUDE.local.md 파일에 규정을 추가해야 했다:
[P4.8] command_run 사용법
shell command 실행 전용 tool입니다. 내장 shell 실행 도구(Bash 등)를 대신 사용하는 것은 규정 위반이며, 예외는
[P4.8d]에 한정됩니다.[P4.8a] 입력 형식
commands: 1개 이상 30개 이하의 배열. 초과·미달은 실행 전 거부됩니다.command_type: "shell_command"+command_line: platform shell(/bin/sh -c,
Windows는cmd.exe /C)에 문자열을 그대로 전달합니다. pipe·redirect 사용 가능.command_type: "argv"+program,args: shell parsing 없이 직접 실행합니다. 인자에 공백·특수문자가 있으면 이 type을 사용하십시오.- 정의되지 않은 field는 거부됩니다(deny_unknown_fields).
[P4.8b] step과 output binding
step(기본 1): 같은 step의 command는 병렬 실행되므로 서로 독립이어야 하고, 다음 step은 이전 step의 모든 결과가 확정된 뒤 시작됩니다.- 독립적인 조회 명령(read/search/list)은 같은 step에 묶어 한 번의 호출로 병렬 실행하십시오. 이전 출력에 의존하는 명령만 뒤 step에 두십시오.
id: 이후 step이 참조할 output binding 이름. 생략하면cmd<index>.- 이전 step의 출력을 소비할 때는 문자열을 손으로 옮기지 말고 binding을 사용하십시오.
- placeholder
#@#${id.field}#@#$: strictly 이전 step의 id만 참조할 수 있습니다.
허용 field는exit_code,stdout,stderr, 그리고 stdout이 JSON object일 때 그 field 경로(예:#@#${make.metadata.revision}#@#$)입니다.- 같은/이후 step 참조, 미지 id, duplicate id는 batch 전체가 실행 전 거부됩니다.
[P4.8c] 실행 제약
cwd: workspace root(서버 시작 cwd) 기준 상대 경로만 허용. 절대 경로,..·symlink로 workspace를 벗어나는 경로는rejected처리됩니다.env:COMMAND_RUN_ENV_ALLOWLIST에 있는 변수만 전달됩니다.timeout_ms: command별 timeout(기본 15000, 상한 600000). 초과 시 process tree가 정리되고 status는timed_out.- batch 전체 timeout 상한은 1800000(30분)입니다. step 경계에서 예산이 소진되면 남은 command는
skipped처리되고, command timeout도 남은 예산으로 clamp됩니다.- stdout·stderr는 각각 256KiB에서 잘리며
stdout_truncated로 표시됩니다.[P4.8d] 결과 해석과 예외
- status:
succeeded|failed|rejected(실행 전 거부) |timed_out|cancelled|skipped(이전 step 실패로 미시작).- 한 command라도 실패하면 그 step의 나머지 결과는 수집되지만 이후 step은
skipped가 되고cancel_reason에 중단 이유가 기록됩니다.- structuredContent(BatchResult)가 원본이며 text content는 요약입니다.
- 예외: workspace 밖 경로 접근, 대화형 명령, server 미연결/장애처럼
command_run이 구조적으로 수행할 수 없는 경우에만 다른 실행 수단을
사용하고 그 사유를 응답에 한 줄로 남기십시오.[P4.8e] 사용 예
{"commands": [ {"command_type": "shell_command", "command_line": "cargo metadata --format-version 1 --no-deps", "id": "meta", "step": 1}, {"command_type": "shell_command", "command_line": "rg -n TODO src | head -20", "step": 1}, {"command_type": "argv", "program": "echo", "args": ["version=#@#${meta.packages.0.version}#@#$"], "step": 2} ]}
STDOUT 도구호출
TUI가 없으니 그다지 이쁜 모습을 볼 수는 없지만 동작하는 건 확실하다. 다만 Kontexus-MCP.structure_reasoning 같은 도구호출이나 codebase-memory-mcp, serena, context7 등의 MCP 서버호출은 배치처리가 안됨.
따라서 일반적인 shell command를 자주 사용하는 프로젝트가 아니라면 토큰 세이빙은 크지 않을 것 같다. 게다가 command-run 도구 사용을 위한 추가된 규정의 규모도 만만찮으니 드라마틱한 차이를 보인다고는 할 수 없다.
