블로그 • AI / Agent
Claude Code는 왜 진짜 AI Agent에 가까워지나? Tool Use, MCP, Session, Permission, JSON Workflow
Claude Code가 Agent처럼 보이는 이유는 세션 하나가 JSON 세 가지를 묶기 때문이다. 다시 열 수 있는 대화, 매번 Tool Use가 통과하는 권한, 시작 때 읽는 MCP. 재개는 --resume, 권한은 settings.json, 도구는 .mcp.json 에서 온다. 하나라도 빠지면 돌아온 작업은 같은 작업이 아니다.
도구 루프 자체는 Coding Agent가 일하는 방식 에 있다. Harness 차이는 Harness 경쟁 에 있다. 이 글은 Claude Code만 나눈다. 세션이 무엇을 되돌리는지, 권한 모드가 언제 바뀌는지, MCP를 언제 다시 읽는지, 직접 남길 워크플로 JSON은 무엇인지.
이 글에서 다루는 내용:
- 세션 재개가 되돌리는 것과 되돌리지 않는 것
- 권한 모드는 세션 상태이고, 규칙은 settings에 있다
- MCP는 세션 시작 때 읽는다. 명령줄 설정은 자동으로 돌아오지 않는다
- 다음에 같은 인자로 재개하기 위한 자신의 워크플로 JSON
- Tool Use 한 번이 문서 세 가지를 어떤 순서로 바꾸는가
먼저 기억할 점: 세션 재개는 시작 인자를 복원하는 일이 아니다. 대화와 일부 권한 모드는 돌아온다. --mcp-config 는 돌아오지 않는다. 아래에서는 세션, 권한, MCP, 자신의 워크플로 JSON 순서로 나눈다.
세션이 되돌리는 것과 되돌리지 않는 것
세션은 프로젝트 디렉터리에 묶인 대화다. 공식 설명은 세션 관리. 기록은 작업 중에 로컬에 쓰이므로 종료 뒤에 돌아올 수 있다.
| 진입 | 돌아오는 것 | 권한 모드 |
|---|---|---|
claude --continue |
이 디렉터리의 최근 대화형 세션 전체. 도구 호출과 결과를 포함 | -p 없는 터미널에서는 공식 표를 따른다. bypassPermissions와 plan은 그대로 돌아오지 않는다 |
claude --resume <name> |
이름으로 그 세션을 바로 재개 | 이름이 유일하면 바로 연다. 겹치면 선택기가 열리고, 저장된 모드는 되돌리지 않는다 |
claude -p --resume |
비대화형 재개. 스크립트용 | 새 claude -p와 같은 모드를 쓴다. plan으로 끝났고 공식 네 조건을 만족할 때만 plan으로 돌아온다 |
재개하면 당시 모델, 아직 유효한 목표, 만료되지 않은 예약 작업도 돌아온다. 백그라운드 Bash는 돌아오지 않는다.
- 돌아온다: 대화 기록, 당시 모델(폐기되었거나 availableModels에 막힌 경우 제외), --agent로 시작한 agent 정의. 두 디렉터리 모두에 없으면 기본 도구로 돌아가며 경고가 나온다.
- 자동으로 돌아오지 않는다:
--mcp-config,--settings,--add-dir, 그리고 세션 중에 /add-dir로 추가한 디렉터리. 재개 명령에 다시 넘긴다. settings.json와 settings.local.json의 설정은 시작 때 다시 읽는다. 다시 넘길 필요 없다.
기록의 기본은 JSONL이고 경로는 ~/.claude/projects/ 아래, 작업 디렉터리에서 만든 폴더다. 공식 문서는 형식이 바뀐다고 적는다. 안정된 계약으로 쓰지 않는다. 안정된 필드는 별도 JSON에 둔다.
권한 모드는 세션과 함께 움직인다
모드는 프롬프트 문장이 아니다. 세션 중에는 Shift+Tab으로 default, acceptEdits, plan을 순환한다. 시작 때는 --permission-mode. 오래 쓰는 기본값은 권한 모드 문서의 permissions.defaultMode 이다. 채팅에서 모드 변경을 부탁해도 이번 문은 바뀌지 않는다.
{
"permissions": {
"defaultMode": "default",
"allow": ["Bash(npm test *)"],
"ask": ["Bash(git push *)"],
"deny": ["Read(./.env)", "Read(./.env.*)"]
}
}
규칙 순서는 Claude Code 권한 에 있다. 더 구체적인 allow도 이미 맞은 deny를 덮지 못한다.
| 재개 방법 | 권한 모드 |
|---|---|
| 터미널 --continue 또는 유일한 이름의 --resume. -p 없음 | 종료 당시 모드를 되돌린다. 예외: bypassPermissions 와 plan 는 새 세션과 같은 모드로 시작한다. auto는 계정이 조건을 만족할 때만 돌아온다. |
| 시작 때 선택기, 또는 여러 세션과 맞는 이름 | 저장된 모드를 되돌리지 않는다. 이번 시작에서 새 세션이 쓸 모드로 시작한다. |
/resume |
대상 세션에 저장된 모드를 되돌리지 않는다. 지금 세션의 모드를 이어 간다. |
규칙을 승인 대기열과 거부 회신으로 만드는 방법은 권한 제어를 연결하는 방법 에 있다. 이 글은 모드를 세션 상태로만 다룬다. 규칙 파일은 재개 때 다시 읽는다.
MCP는 세션 시작 때 읽는다
프로젝트 서버는 저장소 루트의 .mcp.json에 있고 세션 시작 때 읽는다. 파일을 고친 뒤에는 종료하고 다시 연다. 설명은 MCP 연결. 프로젝트 서버를 처음 보면 승인을 요구한다. 복제한 저장소는 동의 없이 이 컴퓨터에서 프로세스를 띄울 수 없다.
{
"mcpServers": {
"docs": {
"type": "http",
"url": "https://code.claude.com/docs/mcp"
}
}
}
- 프로젝트 범위:
.mcp.json. 저장소를 복제한 모두가 공유한다. 먼저 승인한다. - 로컬 범위:
~/.claude.json. local은 자신만, 이 프로젝트만. user는 자신만, 모든 프로젝트. - 플래그
--mcp-config는 이번 시작에만 적용된다. 재개 때 자동으로 돌아오지 않는다. 다시 넘긴다.
도구 전체 이름은 mcp__docs__ 같은 접두사를 쓴다. 권한 규칙은 이 전체 이름에 맞춘다. 서버 안의 짧은 이름만 쓰지 않는다.
직접 남기는 워크플로 JSON
기록 JSONL은 안정된 계약이 아니다. 아래 문서는 자신의 것이다. 다음에 재개할 때 무엇을 넘길지 적는다. Claude Code 요청 본문이 아니고 CLI도 읽지 않는다.
{
"name": "auth-refactor",
"cwd": "/repo/app",
"permission_mode": "default",
"settings": ".claude/settings.json",
"mcp_config": ".mcp.json",
"resume": ["--resume", "auth-refactor"],
"last_tool": {
"name": "mcp__docs__search",
"decision": "allow"
}
}
name은 claude -n 또는 /rename으로 정한 이름이라 --resume가 이름으로 찾는다. cwd는 당시 프로젝트 디렉터리여야 한다. 세션은 디렉터리별로 저장된다.
-
1
먼저 세션을 맞춘다
name를 --resume에 넘긴다.cwd는 어느 프로젝트 디렉터리에 기록이 있는지 정한다. 디렉터리가 다르면 같은 이름도 찾지 못한다. -
2
그다음 권한 모드를 맞춘다
permission_mode를 재개 명령의--permission-mode에 복사한다. 선택기와 /resume는 옛 모드를 되돌려 주지 않는다. -
3
마지막으로 MCP를 붙인다
mcp_config가 저장소 안 파일을 가리키면 시작 때 다시 읽는다. 당시 명령줄 파일에 의존했다면 그 경로를--mcp-config에 넣는다.
Tool Use 한 번이 문서 세 가지를 어떻게 바꾸는가
한 턴은 프롬프트를 한 단락 더 쓰는 일이 아니다. 순서는 고정이다.
-
1
읽기
세션은 기존 대화를 불러오고 settings.json과 .mcp.json을 다시 읽는다. 명령줄 MCP는 이번에 넘겼을 때만 있다.
-
2
호출 제안
모델은 tool_use를 낸다. 도구 전체 이름과 input. MCP 도구에는 서버 접두사가 붙는다.
-
3
권한 통과
deny, ask, allow 순으로 판정한다. deny는 실행하지 않는다. ask는 사람을 기다린다. allow가 되어야 도구를 호출한다.
-
4
회신
결과는 세션 기록에 추가된다. 자신의 워크플로 JSON은
last_tool만 갱신한다. 기록 전체를 복사하지 않는다.
다음 재개 때는 어느 도구에서 멈췄는지, 당시 모드, MCP를 어느 파일에서 읽었는지 알 수 있다. 기록 자체는 Claude Code가 저장한다.
다른 두 글과의 분담
| Coding Agent가 일하는 방식 | Harness 경쟁 | 이 글 | |
|---|---|---|---|
| 답하는 질문 | 도구 루프가 일반적으로 어떻게 도는가 | 각 껍질이 어디서 다른가 | Claude Code 세션을 재개할 때 JSON 세 가지가 각각 무엇을 맡는가 |
| 여기서 찾지 말 것 | 도구 호출 개요를 한 편 더 | 제품 비교표를 한 장 더 | JSONL 기록을 안정된 API로 파싱하는 일 |
JSONNote에서 워크플로 JSON 검사
-
1
포맷
JSON 포맷 으로 settings.json과 워크플로 기록을 연다. 주석이나 끝의 쉼표는 다음 시작 때 Settings Error가 된다.
-
2
워크플로 기록 검증
아래 Schema를 JSON Schema 에 붙인다. name이나 cwd가 없거나 permission_mode가 열거 밖이면 재개 전에 고친다.
-
3
권한 규칙 비교
deny / allow를 바꾸기 전후를 JSON Diff 로 봐서
deny가allow로 옮겨졌는지 확인한다. 이 변화는 세션 이름보다 사람이 볼 가치가 있다.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"additionalProperties": false,
"required": ["name", "cwd", "permission_mode", "settings", "mcp_config"],
"properties": {
"name": { "type": "string", "minLength": 1 },
"cwd": { "type": "string", "minLength": 1 },
"permission_mode": {
"enum": ["default", "acceptEdits", "plan", "auto", "dontAsk", "bypassPermissions"]
},
"settings": { "type": "string", "minLength": 1 },
"mcp_config": { "type": "string", "minLength": 1 },
"resume": { "type": "array", "items": { "type": "string" } },
"last_tool": {
"type": "object",
"required": ["name", "decision"],
"properties": {
"name": { "type": "string" },
"decision": { "enum": ["allow", "deny", "ask"] }
}
}
}
}
자주 묻는 질문
resume 뒤에도 MCP 서버가 있나요?
.mcp.json 또는 ~/.claude.json에 있는 서버는 시작 때 다시 읽는다. --mcp-config로만 넘긴 서버는 자동으로 돌아오지 않는다. 재개할 때 다시 넘긴다.
권한 모드도 대화와 함께 돌아오나요?
항상은 아니다. -p 없는 터미널 --continue 또는 유일한 이름의 --resume는 공식 표를 따른다. bypassPermissions와 plan은 그대로 돌아오지 않는다. 선택기와 /resume는 이번 시작의 모드를 쓴다.
~/.claude/projects의 JSONL을 워크플로로 파싱해도 되나요?
하지 않는다. 공식 문서는 기록 형식을 바뀌는 내부 파일로 본다. 안정된 필드는 이 글의 워크플로 JSON에 이름, 디렉터리, 모드, 설정 경로, 마지막 도구 결정만 적는다.
대화에서 모델에게 권한 모드를 바꾸라고 하면 되나요?
안 된다. 모드는 Shift+Tab, --permission-mode, settings의 defaultMode가 정한다. 프롬프트로는 바뀌지 않는다.
이것은 승인 대기열과 같은 것인가요?
아니다. 여기서 permission_mode는 이번 세션의 문이다. 대기열, 거부 회신, tool_use_id는 권한 제어 글에 있다. 둘 다 필요하다. 모드는 물을지 정하고, 대기열은 답을 어떻게 저장할지 정한다.
정리
Claude Code가 Agent처럼 보이는 이유는 세션이 대화, 권한 모드, MCP 도구를 다시 열 수 있는 작업 하나로 묶기 때문이다. 대화를 되돌리는 것은 시작 인자를 되돌리는 일이 아니다. JSONL 기록은 CLI에 맡기고 자신의 워크플로 JSON을 남긴다.
결론: 세션은 이름과 디렉터리로 찾는다. 선택기와 /resume에서는 권한 모드를 명시해서 다시 넘긴다. --mcp-config는 재개할 때마다 다시 붙인다.
다음: 워크플로 기록을 검증한 다음 안의 resume 인자로 세션을 연다.