headersHelper를 맹신하지 마세요 — Claude Code 2.1.238이 바꾼 MCP 신뢰 경계
한 줄 요약: Claude Code 2.1.238부터 프로젝트·플러그인 headersHelper는 폴더 신뢰가 확인되기 전에는 돌지 않고, 돌더라도 자격 증명성 환경 변수를 물려받지 않습니다. 공유 .mcp.json은 설정 파일이 아니라 셸 실행 표면으로 다루는 편이 맞습니다.
왜 중요한가
에이전트 스택에서 MCP는 “도구를 붙이는 포트”처럼 보이지만, HTTP/SSE 서버에 OAuth가 없으면 팀은 자주 headersHelper로 짧은 수명의 토큰·사내 SSO 헤더를 붙입니다. 문서는 이를 연결 시점에 셸 명령을 실행해 stdout의 JSON 헤더를 합친다고 분명히 적습니다. 타임아웃은 10초이고, Claude Code 쪽 캐시는 없습니다.
문제는 편의입니다. 저장소에 .mcp.json과 헬퍼 스크립트를 커밋하면 온보딩은 빨라지지만, 그 헬퍼는 내가 쓰지 않은 명령일 수 있습니다. 2.1.238 이전에는 claude -p나 SDK 세션이 프로젝트/로컬 스코프 헬퍼를 폴더 신뢰 검사 없이 돌릴 수 있었고, 인터랙티브에서도 부모 폴더 신뢰만으로 넘어가는 구멍이 있었습니다. CI에서 “조용히 토큰을 찍어 헤더를 만든다”는 패턴이 보안 리뷰 없이 재현되기 쉬운 구조였습니다.
이전과 무엇이 다른가
| 축 | 이전(요약) | 2.1.238 이후 |
|---|---|---|
프로젝트 .mcp.json / 로컬 스코프 헬퍼 | -p/SDK에서 신뢰 검사 약함 | 해당 폴더의 trust dialog 수락 후에만 실행 |
| 부모 폴더 신뢰 | 사실상 우회로로 쓰이기 쉬움 | 카운트하지 않음 |
| 자격 증명 env | 프로세스 env를 그대로 물려받기 쉬움 | 프로젝트·플러그인·프로젝트 agent 파일 헬퍼는 TOKEN/SECRET/KEY 등 패턴 변수와 고정 목록을 제거 |
| user / managed / claude.ai / SDK 헬퍼 cwd | 시작 디렉터리에 묶이기 쉬움 | Claude config dir(~/.claude 등) 기준 |
같은 주간에 GitHub Copilot for JetBrains는 managed-settings.json으로 MCP allow/deny·플러그인 마켓·OpenTelemetry·Bypass Approvals 금지를 조직 정책 파일로 밀어 넣었습니다. Claude 쪽 변화는 “중앙 허용 목록”이라기보다 폴더 단위 실행 게이트 + 헬퍼 환경 격리에 가깝습니다. 둘 다 “에이전트가 붙는 MCP는 개인 취향이 아니다”라는 신호지만, 통제 계층이 다릅니다.
코드·설정 예시
프로젝트에 커밋하는 HTTP MCP 예시입니다. 헬퍼는 파일/시크릿 스토어에서 토큰을 읽고, stdout에는 문자열 키-값 JSON만 냅니다.
{
"mcpServers": {
"internal-api": {
"type": "http",
"url": "https://mcp.internal.example.com",
"headersHelper": "/opt/bin/get-mcp-auth-headers.sh"
}
}
}
#!/usr/bin/env bash
# get-mcp-auth-headers.sh — 프로젝트 헬퍼는 ANTHROPIC_API_KEY 등을 기대하지 말 것
set -euo pipefail
TOKEN="$(cat "${MCP_TOKEN_FILE:?set MCP_TOKEN_FILE to a secret file}")"
# 또는: op read "op://Eng/mcp/token" 등 파일/스토어 경로
printf '{"Authorization":"Bearer %s"}\n' "$TOKEN"
신뢰가 없으면 헬퍼는 건너뛰고 정적 headers만으로 연결을 시도합니다. -p/SDK에서는 서버마다 stderr에 headersHelper not run 한 줄이 남을 수 있습니다. CI에서 대화 상자 없이 신뢰하려면 문서가 안내하는 대로 ~/.claude.json의 projects["<path>"].hasTrustDialogAccepted를 true로 두는 경로를 검토하세요. 경로 키는 팀이 실제로 Claude를 띄우는 디렉터리와 일치해야 합니다.
플러그인/프로젝트 헬퍼의 cwd·스코프 규칙도 바뀌었습니다. user/managed/claude.ai 쪽 헬퍼는 config dir에서 돌고, 프로젝트 .mcp.json 헬퍼는 세션을 시작한 디렉터리를 기준으로 상대 경로를 해석합니다. 상대 경로 헬퍼를 쓸 거면 PATH/절대 경로로 고정하는 편이 덜 아픕니다.
실무에서 쓰는 법
- 스코프부터 적기. 커밋되는
.mcp.json인지, user/local인지, 플러그인인지에 따라 env 제거·cwd·신뢰 규칙이 갈립니다. - 헬퍼를 “설치 스크립트”로 리뷰. stdout JSON 스키마, 10초 제한, 재연결마다 재실행, 401/403 시 한 번 재시도라는 동작 계약을 팀에 공유하세요.
- 자격 증명은 파일/스토어.
ANTHROPIC_API_KEY나*_TOKEN을 헬퍼가 읽어 “우연히” 동작하던 패턴은 프로젝트 스코프에서 깨집니다. - 실패면
/mcp로 재연결. 문서상 헬퍼는 연결·재연결 시 다시 돌고, 도구 호출이 401/403이면 같은 규칙으로 한 번 더 돌립니다. - 부모 폴더 신뢰에 기대지 않기. monorepo에서 상위만 trust 해두고 하위
.mcp.json을 돌리던 습관은 이제 의도적으로 막힙니다.
처음에는 “어제까지 CI에서 되던 헬퍼가 왜 headersHelper not run이지?”에서 막혔습니다. 원인은 토큰 만료가 아니라, -p 경로에서 폴더 신뢰가 더 이상 자동으로 통과하지 않는다는 쪽이었습니다. 토큰 파일을 시크릿 마운트로 옮기고 trust 키를 맞춘 뒤에야 다시 붙었습니다.
시니어 엔지니어 관점
에이전트 시대의 보안 회귀는 대개 “새 CVE”보다 조용히 실행되던 셸에서 납니다. headersHelper는 이름이 헤더처럼 들리지만, 실질은 shell: true에 가까운 연결 훅입니다. 2.1.238은 그 훅을 (1) 폴더 신뢰 게이트, (2) 자격 증명 env 격리, (3) cwd를 설정 출처에 고정하는 세 줄로 조였습니다. 완벽한 샌드박스는 아닙니다. 신뢰한 뒤에는 여전히 그 명령이 돕니다. 다만 “클론만 하면 CI가 알아서 MCP에 붙는다”는 기본값을 걷어낸 것은, 플랫폼 팀이 리뷰 체크리스트에 넣을 만한 변화입니다.
Cursor에서 써보기
Cursor 클라우드/로컬 에이전트도 MCP·플러그인·allowlist를 통해 비슷한 실행 표면에 닿습니다. Claude 전용 API를 Cursor에 그대로 이식한다고 주장할 필요는 없습니다. 대신 리뷰 습관을 옮기세요.
- PR에
.mcp.json/ 헬퍼 스크립트 / agent 파일 인라인 MCP가 들어오면 신뢰·시크릿 경로를 코멘트 템플릿에 넣기 - “헬퍼가 프로세스 env의
*_TOKEN에 의존하는가?”를 체크 - Cursor 쪽 구독·자동화 에이전트가 같은 저장소를 돌릴 때, 어느 환경에서 trust가 이미 승인됐는지를 런북에 적기
에이전트가 밤사이 PR을 고치는 흐름일수록, “헤더 헬퍼 한 줄”이 빌드 머신에서 무엇을 실행할 수 있는지가 곧 사고 반경입니다.
FAQ
Q. 정적 headers만 쓰면 신뢰가 필요 없나요?
A. 헬퍼를 건너뛰는 동안에는 정적 헤더로만 연결을 시도합니다. 다만 정적 헤더에 시크릿을 넣는 것은 커밋 사고 위험이 커서, 짧은 수명 토큰이라면 헬퍼+파일 스토어가 보통 낫습니다.
Q. user 스코프 헬퍼도 env가 잘리나요?
A. 문서 기준 제거 대상은 주로 프로젝트 .mcp.json / 플러그인 / 프로젝트·--add-dir agent 파일입니다. user·managed·claude.ai·SDK/--mcp-config 쪽은 자격 증명 env를 유지한다고 되어 있습니다. 스코프를 옮기면 동작이 달라지니 팀 표준 스코프를 하나로 고정하세요.
Q. headersHelper not run이 뜨면?
A. 해당 시작 폴더의 trust가 없거나, 부모 신뢰만 있는 상태일 가능성이 큽니다. 인터랙티브에서 대화 상자를 수락하거나, CI라면 hasTrustDialogAccepted 경로를 맞춘 뒤 /mcp로 재연결하세요.
Q. 헬퍼 출력이 캐시되나요?
A. Claude Code는 헬퍼 결과를 캐시하지 않습니다. 토큰 재사용 정책은 스크립트 책임입니다.
참고 자료
- Claude Code v2.1.238 release notes
- Claude Code MCP docs — dynamic headers & trust
- Enterprise managed settings in GitHub Copilot for JetBrains (비교)
앞으로 MCP 온보딩 체크리스트의 첫 줄은 “어떤 모델이 빠른가”보다 누가 어떤 폴더에서 어떤 셸을 돌릴 권한이 있는가가 될 가능성이 큽니다. 헬퍼를 커밋할 때마다 그 질문을 한 번 더 하면, 에이전트 자동화의 속도는 유지하면서 사고 반경만 줄일 수 있습니다.