Claude Code를 사용하기 시작하면, 설정 파일인 settings.json을 스크립트에서 수정하고 싶어지는 경우가 자주 있습니다. 예를 들어, 여러 환경에 걸쳐 일괄적으로 설정을 배포하거나, CI(지속적 통합) 과정에서 설정을 주입하거나, 개발 멤버 간의 설정을 동기화하는 경우 등이 있습니다.
하지만 파일을 직접 수정하려다가 쉼표 누락이나 괄호 불일치로 JSON을 손상시켜 Claude Code가 실행되지 않는 — 이는 초보자가 빠지기 쉬운 함정입니다. 본 글에서는 Python의 json 모듈과 딕셔너리 조작을 결합하여, 구조를 손상시키지 않고 settings.json을 안전하게 편집하는 구체적인 방법을 설명합니다.
설정 파일을 수정할 때 가장 먼저 떠오르는 방법은 sed나 Python의 문자열 replace()를 이용한 치환일 것입니다. 예를 들어, 특정 훅(hook)을 추가하고 싶을 경우 다음과 같은 코드를 작성하기 쉽습니다.
# ❌ 위험한 예: 문자열 치환으로 JSON 편집
with open("settings.json", "r") as f:
content = f.read()
...
이러한 방식에는 여러 문제가 있습니다.
"hooks" 키가 존재하지 않으면 치환이 작동하지 않습니다.
- 이미 같은 훅이 존재하는 경우 중복 엔트리가 발생합니다.
- 마지막 쉼표 유무에 따라 구문 오류가 발생할 수 있습니다.
- 주석이 포함된 JSON(일부 도구에서 허용)을 처리할 수 없습니다.
가장 치명적인 것은 '3번'입니다. 치환된 문자열에 쉼표를 빼먹거나, 반대로 이중 쉼표가 되면 다음 실행 시 JSONDecodeError와 같은 오류로 멈추게 됩니다. 설정 파일이 손상되면 CI가 실패하고, 팀 멤버들이 혼란을 겪는 연쇄 반응이 일어납니다.
안전한 접근 방식은 파일을 '문자열'이 아닌 '데이터 구조(딕셔너리)'로 읽고 편집한 후 다시 쓰는 것입니다. Python의 json 모듈을 사용하면, 괄호나 쉼표 관리를 완전히 맡길 수 있습니다.
import json
from pathlib import Path
SETTINGS_PATH = Path("/path/to/.claude/settings.json")
...
핵심 포인트는 두 가지입니다.
indent=2를 지정하여 사람이 읽을 수 있는 형식으로 다시 쓰는 것 (나중에 diff 확인이 용이해집니다).
ensure_ascii=False로 일본어 등을 그대로 출력하는 것 (이스케이프 시퀀스 나열을 피할 수 있습니다).
실제로 'PreToolUse 훅을 1건 추가하는' 처리를 작성해 보겠습니다. 핵심은 기존 훅을 덮어쓰지 않고, 추가하여 병합(merge)하는 것입니다.
def add_pre_tool_use_hook(settings: dict, matcher: str, command: str) -> dict:
"""PreToolUse 훅을 안전하게 추가합니다.
- hooks 키가 없으면 생성합니다.
...
"""
이 구현의 강점은 **멱등성(Idempotency)**입니다. 문자열 치환으로는 실현하기 어려운 속성이지만, 딕셔너리 조작이라면 '이미 존재하는지?'를 직관적으로 확인할 수 있습니다. CI에서 여러 번 실행해도 항상 같은 상태가 유지된다는 것은 실제 운영 환경에서 매우 중요합니다.
아무리 조심해도 사람은 실수합니다. 스크립트 실행 시에는 반드시 백업과 구문 검증을 거치는 것을 권장합니다.
import shutil
from datetime import datetime
def safe_update(path: Path, updater) -> None:
...
이처럼 json.dumps()로 한 번 시리얼라이즈를 시도해 보면, 순환 참조나 비-JSON 타입의 값이 혼입되었을 경우 파일을 손상시키기 전에 예외로 멈출 수 있습니다. 작은 노하우지만, 실무에서는 여러 번 큰 도움이 되었습니다.
settings.json의 안전한 편집은 Claude Code 운영 자동화에서 첫 번째 벽이 됩니다. 본 글에서 전달하고 싶었던 핵심 요점은 다음과 같습니다.
문자열 치환 대신 반드시 구조(딕셔너리)로 다루기 | setdefault()와 중복 검사로 멱등성 확보하기 | 백업과 json.dumps()를 이용한 검증을 세트로 구성하기
이러한 방법들만 지켜도 CI 환경에서의 설정 배포나 팀원 간의 배포 시 발생하는 트러블을 크게 줄일 수 있습니다. 저 자신도 처음에는 문자열 치환(string replacement)으로 망가뜨리면서 배웠지만, 딕셔너리 조작(dictionary operation)으로 전환한 이후로는 설정 파일 손상 사고가 0이 되었습니다. 꼭 자신의 리포지토리에서도 헬퍼 스크립트(helper script)로 가져다 사용해 보시길 바랍니다.
본 기사는 개인 Zenn에도 공개되어 있습니다.