이것은 MCP가 아닙니다.
Clojure와 함께 작동하는 LLM 코딩 어시스턴트(coding assistants)를 위한 간단한 CLI 도구들입니다.
요약 (TL;DR): LLM 코딩 어시스턴트를 활용한 Clojure 개발을 위한 세 가지 CLI 도구:
clj-nrepl-eval
- 커맨드 라인(command line)에서의 nREPL 평가 (evaluation)
clj-paren-repair-claude-hook
- 훅(hooks)을 통한 구분자 자동 수정 (Claude Code)
clj-paren-repair
- 온디맨드(On-demand) 구분자 수정 (Gemini CLI, Codex 등)
LLM은 Clojure 코드를 편집할 때 괄호(parentheses), 대괄호(brackets), 중괄호(braces)가 일치하지 않는 등의 구분자 오류를 발생시킵니다. 이는 AI가 구분자 오류를 수정하는 데 반복적으로 실패하여 토큰을 낭비하고 진행을 막는 **"괄호 편집 데스 루프 (Paren Edit Death Loop)"**로 이어집니다.
부차적인 문제: LLM 코딩 어시스턴트는 평가를 위해 상태가 유지되는(stateful) Clojure REPL에 연결해야 합니다.
이 도구들은 두 가지 문제를 모두 해결합니다.
| 도구 | 사용 사례 |
|---|
clj-nrepl-eval | 모든 LLM으로부터의 REPL 평가 |
clj-paren-repair-claude-hook | Claude Code (또는 Claude 훅을 지원하는 모든 LLM) |
clj-paren-repair | Gemini CLI, Codex CLI, 셸(shell)을 사용하는 모든 LLM |
훅(hook) 도구 설치:
bbin install https://github.com/bhauman/clojure-mcp-light.git --tag v0.2.2
참고: 훅은 ~/.claude/settings.json에 설정되지 않으면 작동하지 않습니다.
nREPL 평가 도구 설치:
bbin install https://github.com/bhauman/clojure-mcp-light.git --tag v0.2.2 --as clj-nrepl-eval --main-opts '["-m" "clojure-mcp-light.nrepl-eval"]'
온디맨드 수정 도구 설치:
bbin install https://github.com/bhauman/clojure-mcp-light.git --tag v0.2.2 --as clj-paren-repair --main-opts '["-m" "clojure-mcp-light.paren-repair"]'
중요한 설정 및 사용 세부 사항은 아래의 개별 도구 섹션을 참조하십시오.
선택 사항:
- parinfer-rust - 사용 가능한 경우 더 빠른 구분자 수정
커맨드 라인에서 Clojure 코드를 평가하기 위한 nREPL 클라이언트입니다.
이는 코딩 어시스턴트(coding assistants)가 셸 호출(shell calls)을 통해 REPL 평가(eval)에 접근할 수 있도록 합니다. 특히 LLM 상호작용을 위해 설계되었으며, LLM이 MCP 서버를 구성할 필요 없이 자신의 REPL 세션을 발견하고 관리할 수 있게 해줍니다.
- 실행 중인 REPL에서 LLM이 코드를 평가할 수 있도록 허용
- 대상별로 지속적인 세션(persistent sessions) 유지
- nREPL 포트 자동 발견
- 평가 전 구분자(delimiters) 자동 수정
- LLM을 안내하는 유용한 출력 제공
설치는 두 단계로 이루어집니다. 먼저 커맨드 라인 도구를 설치한 다음, 코딩 어시스턴트에게 clj-nrepl-eval에 대해 알려주어야 합니다.
bbin install https://github.com/bhauman/clojure-mcp-light.git --tag v0.2.2 --as clj-nrepl-eval --main-opts '["-m" "clojure-mcp-light.nrepl-eval"]'
또는 로컬 체크아웃(local checkout)에서:
bbin install . --as clj-nrepl-eval --main-opts '["-m" "clojure-mcp-light.nrepl-eval"]'
nREPL을 시작하고 테스트 평가를 수행하여 설치 및 작동 여부를 확인하세요.
# 이 누락된 괄호는 구분자가 자동으로 수정됨을 보여주기 위한 것입니다
clj-nrepl-eval -p 7888 "(+ 1 2 3"
# => 6
다음 접근 방식 중 하나 이상을 선택하세요. 각 방식에는 트레이드오프(trade-offs)가 있습니다:
| 접근 방식 | 가용성 | 정보 사용 시점 | 최적의 용도 |
|---|
| 사용자 지정 지침 (Custom instructions) | 모든 LLM 클라이언트 | 항상 컨텍스트 내에 있음 | 가장 간단하고 효과적임 |
| ... | | | |
각 방식은 로컬(프로젝트별) 또는 글로벌(모든 프로젝트)로 설치할 수 있습니다.
가장 간단하고 아마도 가장 효과적인 접근 방식입니다. 모든 LLM 코딩 어시스턴트와 작동합니다.
사용자 지정 지침(custom instructions) 파일에 다음을 추가하세요:
글로벌 (Global): ~/.claude/CLAUDE.md, ~/.gemini/GEMINI.md, ~/.codex/AGENTS.md
로컬 (Local): 프로젝트 루트의 ./CLAUDE.md, ./GEMINI.md, ./AGENTS.md
# Clojure REPL 평가
`clj-nrepl-eval` 명령어가 nREPL을 통해 Clojure 코드를 평가할 수 있도록 경로(path)에 설치되었습니다.
**nREPL 서버 발견:**
...
필요할 때 대화에 REPL 인지(awareness)를 개입시킬 수 있습니다. 대부분의 코딩 어시스턴트에서 사용할 수 있습니다 (설치 방법은 클라이언트마다 다름).
/start-nrepl - 백그라운드에서 nREPL 서버를 시작하고 포트(port)를 보고합니다.
/clojure-nrepl - clj-nrepl-eval에 대한 상세한 사용 정보를 제공합니다.
Claude Code - commands/ 디렉토리 내의 .md 파일을 사용합니다:
# Global: ~/.claude/commands/
# Local: .claude/commands/
mkdir -p ~/.claude/commands
...
Gemini CLI - .toml 파일(docs)을 사용합니다:
# Global: ~/.gemini/commands/
# Local: .gemini/commands/
Codex CLI - .md 파일(docs)을 사용합니다:
# Global: ~/.codex/prompts/
LLM이 실제로 필요할 때 REPL 정보를 가져올 수 있도록 허용합니다. 현재는 Claude Code만 지원합니다.
# Global (all projects)
mkdir -p ~/.claude/skills
cp -r skills/clojure-eval ~/.claude/skills/
...
가장 쉬운 전략: 코딩 세션을 시작하기 전에 nREPL을 시작하세요.
LLM에게 nREPL 사용을 요청하기 전에 nREPL을 먼저 시작하십시오. 이렇게 하면 LLM이 --discover-ports를 통해 현재 프로젝트의 서버 포트를 간단히 찾아낼 수 있습니다. REPL과 상호작용을 시작하기 위한 절차가 매우 최소화됩니다.
고급: LLM이 nREPL 세션을 시작하고 관리하도록 하세요.
Claude 및 기타 LLM은 백그라운드에서 nREPL 서버를 시작하고 출력에서 포트를 읽어오는 작업을 완벽하게 수행할 수 있습니다. 또한 잘못된 평가(eval)로 인해 서버가 멈춘 경우 서버를 종료할 수도 있습니다.
코딩 어시스턴트 내부에서 clj-nrepl-eval을 사용하기 시작하면, 위 프롬프트들을 귀하의 특정 프로젝트와 워크플로(workflow)에 맞게 조정하는 방법이 빠르게 명확해질 것입니다.
Claude Code 훅(Hooks)을 사용하면 Claude의 도구 호출(tool calls) 전후에 셸 명령어를 실행할 수 있습니다. 이 훅은 쓰기/편집(Write/Edit) 작업을 가로채서 파일 시스템에 반영되기 전에 구분자(delimiter) 오류를 자동으로 수정합니다.
제 사용 경험상, 이 훅들은 감지된 오류의 100%를 해결했습니다.
참고: 다른 LLM 클라이언트들이 훅 지원을 추가함에 따라, 클라이언트별 특화된 훅 도구를 생성하고 출시하는 것이 목적입니다. 예를 들어, Gemini CLI가 훅을 추가하면 clj-paren-repair-gemini-hook 도구를 사용할 수 있게 될 것입니다.
왜 MCP 도구 대신 훅을 사용하나요?
MCP 기반 편집 도구를 사용하면 Claude Code의 네이티브 UI 통합 기능을 잃게 됩니다. 즉, 도구 호출 (tool calls) 형식이 제대로 갖춰지지 않아 읽기 어려워집니다. 훅 (Hooks)을 사용하면 Claude Code가 고유의 편집/쓰기 (Edit/Write) 도구를 사용하여 정상적으로 작동하게 함으로써, 익숙한 깔끔한 디프 (diff) UI를 유지하면서도 백그라운드에서 구분자 (delimiter) 오류를 투명하게 수정할 수 있습니다.
- 디스크에 기록되기 전에 오류를 투명하게 수정합니다.
- 토큰을 전혀 사용하지 않습니다 — LLM 호출 외부에서 발생합니다.
- Claude Code의 네이티브 디프 (diff) UI 및 도구 통합을 보존합니다.
- 한 번 전역적으로 설치하면 모든 Clojure 파일 편집에 적용됩니다.
bbin install https://github.com/bhauman/clojure-mcp-light.git --tag v0.2.2
또는 로컬 체크아웃에서:
bbin install .
~/.claude/settings.json에 추가:
{
"hooks": {
"PreToolUse": [
...
--cljfmt
cljfmt를 사용하여 자동 코드 포매팅 (formatting)을 활성화합니다.
--stats
- 통계 추적을 활성화합니다 (
~/.clojure-mcp-light/stats.log에 기록됨).
--log-level LEVEL
- 로그 레벨을 설정합니다 (trace, debug, info, warn, error).
--log-file PATH
- 로그 파일 경로를 설정합니다 (기본값:
./.clojure-mcp-light-hooks.log).
-h, --help
PreToolUse 훅은 쓰기/편집 (Write/Edit) 작업 전에 실행되어 내용이 기록되기 전에 수정합니다.
PostToolUse 훅은 편집 작업 후에 실행되어 발생한 문제를 수정합니다.
SessionEnd 훅은 Claude Code 세션이 종료될 때 임시 파일을 정리합니다.
쓰기 작업 (Write operations): 구분자 오류가 감지되면, 기록하기 전에 parinfer를 통해 내용이 수정됩니다. 수정이 불가능한 경우 쓰기 작업이 차단됩니다.
편집 작업 (Edit operations): 편집 전에 백업이 생성됩니다. 편집 후 구분자 오류가 존재하면 자동으로 수정됩니다. 수정이 불가능한 경우 파일이 백업으로부터 복구됩니다.
통계 추적은 이러한 도구들이 잘 작동하고 있는지 검증하는 데 도움이 됩니다. 언젠가 모델이 구분자 오류를 더 이상 생성하지 않거나, 어시스턴트가 내부적으로 parinfer를 포함하게 되면 Clojure 개발자들에게 이 도구들이 더 이상 필요하지 않을 수도 있습니다. 추적을 통해 우리는 그날이 언제인지 알 수 있습니다.
구분자 이벤트를 추적하려면 --stats를 추가하세요:
clj-paren-repair-claude-hook --cljfmt --stats
통계(Stats)는 ~/.clojure-mcp-light/stats.log에 작성됩니다.
EDN 형식:
{:event-type :delimiter-error, :hook-event "PreToolUse", :timestamp "2025-11-09T14:23:45.123Z", :file-path "/path/to/file.clj"}
{:event-type :delimiter-fixed, :hook-event "PreToolUse", :timestamp "2025-11-09T14:23:45.234Z", :file-path "/path/to/file.clj"}
포함된 통계 요약 스크립트를 사용하세요:
./scripts/stats-summary.bb
샘플 출력:
clojure-mcp-light Utility Validation
============================================================
Delimiter Repair Metrics
...
디버깅을 위해 로깅 활성화:
# 디버그 레벨
clj-paren-repair-claude-hook --log-level debug --cljfmt
# 트레이스 레벨 (최대 상세도)
...
echo '{"hook_event_name":"PreToolUse","tool_name":"Write","tool_input":{"file_path":"test.clj","content":"(def x 1)"}}' | clj-paren-repair-claude-hook
Claude Code에서 후크가 실행되는지 확인:
Claude Code가 Clojure 파일을 편집한 후, 도구 출력을 확장하여 후크 메시지를 확인하세요. 터미널에서 ctrl-r을 누르거나 (편집을 클릭하고) 다음 메시지들 주변을 살펴보세요:
⎿ PreToolUse:Edit hook succeeded:
...
⎿ PostToolUse:Edit hook succeeded:
이러한 메시지가 보이지 않으면, ~/.claude/settings.json의 후크 구성이 올바른지 확인하세요.
구분자 복구 테스트:
Claude Code에게 의도적으로 잘못된 Clojure(예: 닫는 괄호 누락)를 작성하도록 요청하여 후크가 이를 자동으로 수정하는지 검증하세요.
완벽한 커버리지를 위해 clj-paren-repair와 결합하세요. 후크는 Edit/Write 도구를 처리하지만, LLM은 Bash(sed, awk)를 통해서도 편집할 수 있습니다. 두 도구를 모두 사용하면 모든 경우를 포착합니다.
후크를 지원하지 않는 LLM 코딩 어시스턴트(예: Gemini CLI 및 Codex CLI)를 위한 셸 명령어입니다. LLM이 구분자 오류를 만나면, 이를 수동으로 복구하려고 시도하는 대신 이 도구를 호출하여 수정합니다.
핵심 통찰 (The key insight): AI가 "괄호 편집 데스 루프 (Paren Edit Death Loop)"—구분자 오류를 수정하는 데 반복적으로 실패하는 현상—에 빠진 것을 관찰할 때, 우리는 해결책을 찾기 위한 필사적인 시도를 목격하게 됩니다. clj-paren-repair는 이러한 동작을 단축시켜 탈출 경로를 제공합니다.
작동 원리 (Why this works): 최신 SOTA (State-of-the-Art) 모델들은 아주 미세한 구분자 불일치만 있을 뿐, 매우 정확한 편집 내용을 생성합니다. 이러한 오류는 parinfer가 안정적으로 수정할 수 있을 만큼 사소합니다. 이 간단한 해결책은 놀라울 정도로 잘 작동합니다.
Hooks vs clj-paren-repair: Hooks를 사용할 수 있는 경우에는 Hooks가 명백한 승자입니다. Hooks는 토큰을 전혀 사용하지 않으며 LLM 호출 없이 실행되기 때문입니다. 하지만 clj-paren-repair는 셸 (shell) 접근 권한이 있는 모든 LLM과 보편적으로 작동합니다. Gemini CLI에 Hooks 지원이 추가되면 그것을 사용해야 합니다. 그 전까지는 clj-paren-repair로 충분합니다.
두 가지를 함께 사용하기: Hooks가 설정되어 있더라도 clj-paren-repair를 사용할 수 있으면 완벽한 커버리지를 제공합니다. Hooks는 Edit/Write 도구를 처리하지만, LLM은 Bash (sed, awk 등)를 통해서도 파일을 편집할 수 있습니다. 두 도구를 모두 갖추면 모든 케이스를 포착할 수 있습니다.
- "괄호 편집 데스 루프 (Paren Edit Death Loop)"로부터의 탈출 경로 제공
- LLM이 구분자 오류를 만났을 때 이를 호출함
- 셸 접근 권한이 있는 모든 LLM과 작동
- cljfmt를 사용하여 파일을 자동으로 포맷팅함
bbin install https://github.com/bhauman/clojure-mcp-light.git --tag v0.2.2 --as clj-paren-repair --main-opts '["-m" "clojure-mcp-light.paren-repair"]'
또는 로컬 체크아웃(local checkout)에서:
bbin install . --as clj-paren-repair --main-opts '["-m" "clojure-mcp-light.paren-repair"]'
clj-paren-repair path/to/file.clj
clj-paren-repair src/core.clj src/util.clj test/core_test.clj
clj-paren-repair --help
사용자의 전역(global) 또는 로컬(local) 커스텀 인스트럭션(custom instructions) 파일(GEMINI.md, AGENTS.md, CLAUDE.md 등)에 추가하세요:
# Clojure Parenthesis Repair
`clj-paren-repair` 명령어가 사용자의 경로(path)에 설치되었습니다.
예시:
...
Claude Code 사용자들을 위한 권장 사항 (Best practice):
- 자동 수정을 위한 Hooks를 설정하세요 (토큰 소모 없음)
- 또한
clj-paren-repair를 갖춰두세요
Bash 기반 편집을 위해 사용 가능합니다 - REPL 평가를 위해 clj-nrepl-eval을 사용하세요.
기타 LLM 클라이언트 (Gemini CLI, Codex 등)의 경우:
clj-paren-repair를 설치하고 커스텀 지침 (custom instructions)을 추가하세요 - REPL 평가를 위해 clj-nrepl-eval을 사용하세요.
문제 A: 출력 결과의 잘못된 구분자 (delimiters) - 해결됨
이 도구들은 편집 결과에서 일치하지 않거나 누락된 괄호를 수정합니다.
문제 B: old_string 매칭 실패 - 해결되지 않음
때때로 LLM이 파일 내용과 정확히 일치하는 old_string을 생성하는 데 어려움을 겪어 편집 실패를 유발할 수 있습니다. 이는 최신 모델에서는 덜 흔하게 발생합니다.
문제 B에 대한 완전한 해결책: ClojureMCP sexp-editing 도구.
ClojureMCP는 포괄적인 Clojure 툴링을 제공하지만: