한 줄 요약: AI 코딩 에이전트의 컨텍스트 윈도우는 모델 응답보다 도구 출력에 먼저 먹힌다. Playwright 스냅샷 한 장이 56KB, GitHub 이슈 20개가 59KB다. mksglu/context-mode는 MCP 서버로 그 출력을 샌드박스에 가두고 stdout만 넘기며(~98% 절감), SQLite FTS5로 세션·지식을 남기고, PreToolUse 훅으로 17개 플랫폼에 라우팅을 강제한다. 오늘은 라이선스(ELv2)·npm 1.0.169·별 27,377 수치를 재확인하고, Headroom(CCR 압축 프록시)과의 차이를 분명히 한 뒤 아키텍처를 코드·문서로 해부한다.

왜 지금 이 저장소인가
컨텍스트 최적화 논의는 보통 두 갈래다. 하나는 프롬프트·메시지를 줄이는 쪽(요약, 압축, 캐시 보존), 다른 하나는 도구가 대화를 오염시키지 않게 막는 쪽이다. 10/10에 다룬 Headroom은 전자—에이전트 앞단 프록시(CCR)가 메시지를 가역 압축한다. Context Mode는 후자—MCP·훅 계층에서 원시 도구 출력을 애초에 컨텍스트에 넣지 않는다. 같은 “컨텍스트 절약” 키워드라도 계층이 다르다.
| 항목 | 확인한 값 (2026-10-13 ~11:51 KST) | 해석 |
|---|---|---|
| 저장소 | mksglu/context-mode — TypeScript MCP 플러그인 |
설명문 그대로 “Context window optimization for AI coding agents. Sandboxes tool output (98% reduction), persists session memory, and enforces routing across 17 platforms via MCP + hooks.” |
| 별 / 포크 | 27,377 / 1,950 (GitHub API) | 오늘 Trending 전체 일간 상위권(약 3위권). 2026-02-23 생성 → 약 7.5개월 만에 2.7만 별 |
| 최근 푸시 | 2026-10-12 18:05 UTC → 10/13 03:05 KST | 전날 밤까지 활발. 트렌딩이 ‘옛 릴리스 재조명’이 아니라 살아있는 프로젝트 |
| npm | context-mode@1.0.169, license Elastic-2.0, 주간 다운로드 ~24.6k |
stats.json 배지 기준 npm 누적 설치 표기 629k+, marketplace 46k+, users 675k+ |
| 라이선스 | Elastic License 2.0 (ELv2). LICENSE 파일·README 배지·npm 필드 일치. GitHub API는 NOASSERTION/Other |
소스 공개·사용·수정·배포 가능. 호스팅/매니지드 서비스로 제공 금지, 라이선스 고지 제거 금지. MIT가 아님 |
| 런타임 | engines.node >= 22.5.0 또는 Bun. Linux+Node<22.5는 설치 거부(#564) |
Node≥22.5면 node:sqlite, Bun이면 bun:sqlite. 그 외 better-sqlite3. V8 madvise SIGSEGV 회피 설계 |
| 작성자 | Mert Koseoglu (mksglu) |
HN #1(570+ points) 이력. Discord·Insight 대시보드(context-mode.com/insight) 운영 |
이 글은 README, LICENSE, BENCHMARK.md, docs/platform-support.md, package.json 1.0.169, src/adapters/*·hooks/*·configs/* 트리, 그리고 박스에서 Bun으로 돌린 context-mode doctor·index·search 결과를 바탕으로 썼다. 대화형 에이전트 세션 전체 벤치마크는 이 환경에서 재현하지 않았고, 절감률 수치는 프로젝트 BENCHMARK.md(21시나리오)를 인용한다.
Headroom과 무엇이 다른가
독자가 “또 컨텍스트 압축?”이라고 넘기지 않게, 먼저 경계를 긋는다.
| 축 | Headroom (10/10 포스트) | Context Mode (오늘) |
|---|---|---|
| 계층 | 에이전트 앞단 프록시 (CCR) | MCP 서버 + 플랫폼 훅 |
| 무엇을 줄이나 | 이미 대화에 들어간 메시지/콘텐츠를 가역 압축 | 도구 원시 출력이 대화에 들어오기 전에 차단·요약 |
| 세션 기억 | 압축·캐시 보존 중심 | SQLite 이벤트 로그 + FTS5/BM25 + PreCompact 스냅샷 |
| 강제 수단 | 프록시 경로를 타면 적용 | PreToolUse로 Bash/Read/WebFetch 등을 샌드박스로 리다이렉트·차단 |
| 문체/브리비티 | 콘텐츠 변환에 초점 | 라우팅만 강제, 최종 답변 문체는 비강제(벤치마크 열화 이슈 의식) |
| 같이 쓸 수 있나 | 이론상 보완 관계. Headroom은 “이미 들어온 것”, Context Mode는 “들어오지 않게”. 실무에선 훅·프록시 이중 경로의 디버깅 비용을 먼저 계산할 것 | |

네 기둥 (README 구조)
- Context Saving — 샌드박스 도구가 원시 데이터를 컨텍스트 밖으로 유지. 벤치마크 서브토탈 315KB → 5.4~5.5KB(~98%).
- Session Continuity — 파일 편집·git·태스크·에러·사용자 결정을 SQLite에 기록. 압축 시 FTS5 인덱싱 후 BM25로 필요한 조각만 복원.
--continue없으면 이전 세션 즉시 삭제(클린 슬레이트). - Think in Code — LLM이 데이터를 읽지 말고 분석 스크립트를 쓰게.
ctx_execute한 번이 Read 47회(700KB)를 3.6KB로 대체하는 패러다임. 17 클라이언트 + OpenClaw 게이트웨이에서 강제. - No prose-style enforcement — 데이터 경로만 통제. 공격적 단문 프롬프트가 코딩/추론 벤치를 깎는 사례(Moonshot
kimi-k2.5)를 명시적으로 피함.
저장소 구조: 어댑터가 무게다
패키지는 번들(server.bundle.mjs, cli.bundle.mjs)로 배포되고, 소스 트리의 핵심은 플랫폼 어댑터와 훅이다. MCP 도구 본체는 이식 가능하고, 플랫폼마다 다른 것은 훅 와이어 프로토콜이다.
| 경로 | 역할 | 실무 포인트 |
|---|---|---|
server.bundle.mjs / cli.bundle.mjs |
배포 바이너리. bin 엔트리는 CLI | npx 일회성보다 글로벌 context-mode PATH를 권장(훅 커맨드가 글로벌 바이너리를 호출) |
src/server.ts, src/executor.ts, src/search/*, src/session/* |
MCP 도구, 샌드박스 실행, FTS5 검색, 세션 DB | 실행기는 12개 언어 런타임(JS/TS/Python/Shell/Ruby/Go/Rust/PHP/Perl/R/Elixir/C#). Bun 자동 감지 시 JS/TS 3–5× |
src/adapters/* |
플랫폼별 detect·hooks·config | claude-code, gemini-cli, vscode/jetbrains-copilot, copilot-cli, cursor, opencode, kilo(공유 어댑터), openclaw, codex, kimi, qwen-code, antigravity(+cli), kiro, zed, pi, omp … |
hooks/* |
PreToolUse/PostToolUse/PreCompact 등 공통 + 플랫폼 브리지 | routing-block.mjs, session-*.mjs, 보안 번들. fail-open: 훅 실패가 도구를 막지 않음 |
configs/* (18 디렉터리) |
플랫폼별 mcp.json / hooks.json / AGENTS.md·CLAUDE.md·mdc | 훅 가능 플랫폼은 파일을 프로젝트에 쓰지 않고 런타임 주입(과거 자동 쓰기 → git 오염 #158/#164로 비활성) |
docs/platform-support.md |
955줄 능력 매트릭스 | 패러다임 3종: JSON stdin/stdout, TS Plugin, MCP-only. README 세션 표와 교차 검증할 것(Pi/OMP는 플러그인 훅으로 고도화됨) |
skills/, .claude-plugin/, .codex-plugin/, .cursor-plugin/ |
마켓플레이스·플러그인 매니페스트 | Cursor Marketplace는 리뷰 대기(#485/#489). 로컬 폴더/심링크 설치 경로 제공 |
11개 MCP 도구
README·슬래시 커맨드 기준으로 샌드박스 6 + 메타 5다. (ctx_insight는 호스티드 대시보드를 여는 메타 도구.)
| 도구 | 역할 | 벤치/동작 힌트 |
|---|---|---|
ctx_batch_execute |
다중 커맨드·검색을 한 호출로. concurrency 1–8 | 서브에이전트 리서치 986KB → 62KB |
ctx_execute |
12언어 코드 실행, stdout만 컨텍스트 | Playwright snaphot 56KB → 299B |
ctx_execute_file |
파일 처리, 원문 미유출. 프로젝트 경계 가드 기본 ON | 액세스 로그 45KB → 155B. 워크스페이스 밖 경로 거부(#852) |
ctx_index |
마크다운 청크 → FTS5, 제목 가중 5×, Porter stemming | 60KB → 40B(인덱스 포인터) |
ctx_search |
다중 쿼리. Porter+트리그램 → RRF, 근접 재랭킹, Levenshtein 오타 보정 | 온디맨드. Progressive throttle: 9회+면 batch로 리다이렉트 |
ctx_fetch_and_index |
URL fetch→markdown→index. TTL 기본 24h, force/ttl:0 |
캐시 히트 ~0.3KB. IMDS/링크로컬 하드블록, CTX_FETCH_STRICT=1로 RFC1918도 차단 |
ctx_stats / ctx_doctor / ctx_upgrade / ctx_purge / ctx_insight |
절감 리포트, 진단, 업그레이드·훅 수리, 지식베이스 삭제, Insight UI | 터미널에서도 context-mode doctor|index|search|upgrade|insight |

샌드박스·지식베이스·세션 연속성
샌드박스: ctx_execute마다 프로세스 경계가 있는 서브프로세스. 스크립트 간 메모리 공유 없음. stdout만 대화로 간다. 출력이 5KB를 넘고 intent가 있으면 전체를 FTS5에 넣고 intent 매칭 조각만 반환(intent-driven filtering). gh/aws/kubectl 등은 환경·설정 경로를 상속하되 대화에 노출하지 않는 credential passthrough.
지식베이스: 프로젝트별 SQLite(~/.…/context-mode/content/). 검색은 Porter FTS5 MATCH와 trigram을 병렬로 돌린 뒤 Reciprocal Rank Fusion으로 합친다. 멀티텀은 근접 재랭킹, 오타는 Levenshtein. 스니펫은 앞 N자가 아니라 쿼리 주변 윈도우. 100KB 초과 출력은 자동 외부화(포인터만 반환). 14일 지난 content DB는 시작 시 정리.
세션: PreCompact가 우선순위 티어 XML 스냅샷(≤2KB)을 session_resume에 저장하고, SessionStart(또는 OpenCode의 experimental.chat.system.transform 대리)가 Session Guide(Last Request, Tasks, Decisions, Files, Errors, Git, Rules … 약 15 카테고리)를 주입한다. 상세 이벤트는 FTS5에 남겨 ctx_search로 꺼낸다.
| 이벤트 우선순위 | 예시 | 캡처 훅 |
|---|---|---|
| P1 Critical | 파일 R/W, 태스크, 플랜, 규칙 파일, 사용자 프롬프트 | PostToolUse / SessionStart / UserPromptSubmit |
| P2 High | 결정·정정, git, 에러·해소 쌍, 제약, 블로커, 거부된 접근, 환경 | UserPromptSubmit / PostToolUse / PreToolUse |
| P3 Normal | 지연>5s, MCP 사용량, 서브에이전트, 스킬, 외부 참조, 역할 | Pre/PostToolUse |
| P4 Low (먼저 드롭) | 세션 intent 분류, 큰 붙여넣기 참조 | UserPromptSubmit |
플랫폼 매트릭스 (요약)
훅이 있으면 라우팅 준수 ~98%, 지침 파일만이면 ~60%. 훅 없는 Zed·Antigravity IDE는 수동 복사 필수.
| 플랫폼 | 패러다임 | 세션 완성도 | 주의 |
|---|---|---|---|
| Claude Code | 플러그인 마켓 + JSON hooks | Full | 1급 시민. SessionStart가 라우팅을 파일 없이 주입 |
| Gemini CLI / VS·JB Copilot | JSON hooks | High | UserPromptSubmit 부재 → 사용자 결정 캡처 약함 |
| GitHub Copilot CLI | camelCase hooks + plugin | High | CONTEXT_MODE_PLATFORM=copilot-cli 핀으로 Claude 공존 오탐 방지 |
| Cursor | hooks + .mdc rules | Partial | Marketplace 리뷰 대기. sessionStart validator 거부. additional_context 미표출 |
| OpenCode / KiloCode | TS in-process plugin | Full | plugin과 legacy mcp.context-mode 동시 존재 시 도구 0개 — upgrade로 정리 |
| OpenClaw | 네이티브 gateway plugin | High | 별도 MCP 자식 없음. gateway >2026.1.29 필요 |
| Codex CLI / Kimi Code | hooks (+ feature flag) | Partial~High | Codex는 deny만, updatedInput 업스트림 대기(#18491). PreCompact는 빌드 게이팅 |
| Qwen Code | Claude와 동일 와이어 | High | 설정 파일·훅 이름이 Claude 호환 |
| Pi / OMP | extension / plugin | High | 저장소 루트 분리(~/.omp/context-mode/)로 Pi와 충돌 방지 |
| Zed / Antigravity IDE | MCP-only | — | 지침 파일(~60%). Antigravity CLI(agy)는 별도로 부분 훅 |
| Kiro | pre/postToolUse | Partial | agentSpawn(SessionStart) 미배선 |

벤치마크 숫자 (프로젝트 공시)
| 시나리오 | Raw | Context | Saved |
|---|---|---|---|
| Playwright snapshot | 56.2 KB | 299 B | 99% |
| GitHub Issues ×20 | 58.9 KB | 1.1 KB | 98% |
| Access log 500req | 45.1 KB | 155 B | ~100% |
| Analytics CSV 500rows | 85.5 KB | 222 B | ~100% |
| Repo research (subagent) | 986 KB | 62 KB | 94% |
| execute_file 서브토탈 | 315 KB | 5.5 KB | 98% |
| index+search 서브토탈 | 60.3 KB | 11.0 KB | 82% |
| 전체 21시나리오 | 376 KB | 16.5 KB | 96% |
index+search 절감률이 더 낮은 것은 의도다. 코드 예제를 요약하지 않고 원문 청크로 돌려주기 때문. “cleanup 패턴이 있다”는 한 줄보다 useEffect 블록 전체가 코딩에 쓸모 있다. 세션 시간 주장은 약 30분 → 약 3시간(동일 컨텍스트 예산 기준).
설치·실행·박스 스모크
# 권장: Node >= 22.5 또는 Bun
npm install -g context-mode # 또는: bun add -g context-mode
# Claude Code (가장 자동)
/plugin marketplace add mksglu/context-mode
/plugin install context-mode@context-mode
/context-mode:ctx-doctor
# MCP-only 맛보기 (훅·라우팅 없음)
claude mcp add context-mode -- npx -y context-mode
# 터미널 유틸
context-mode doctor
context-mode index ./docs --source project:my-app
context-mode search "authentication middleware" --source project:my-app
context-mode upgrade
| 박스에서 한 일 | 결과 | 함의 |
|---|---|---|
sparse clone + package.json 확인 |
version 1.0.169, license Elastic-2.0, engines ≥22.5 | 배포물과 README 버전 일치 |
| 시스템 Node 20.19.2에서 npm install | postinstall이 Linux+Node<22.5를 명시적 abort | 문서의 #564 가드가 실제로 동작 |
Bun 1.4.2로 cli.bundle.mjs doctor |
Server PASS, FTS5/SQLite PASS, 런타임 7/11(JS/TS/Python/Shell/Go/Rust/Perl) | Bun 경로가 프로덕션 대안. 훅 설정은 이 박스에 없어 FAIL(예상) |
index 샘플 md → search "authentication JWT" |
1 section index, 검색 히트(제목 Auth middleware + 본문) | FTS5 파이프라인 실동작 확인. DB는 어댑터 기본 경로(~/.cursor/context-mode/content/) |
// Think in Code 예시 (README)
// Before: 47 × Read() = 700 KB. After: 1 × ctx_execute() = 3.6 KB.
ctx_execute("javascript", `
const files = fs.readdirSync('src').filter(f => f.endsWith('.ts'));
files.forEach(f => console.log(f + ': ' +
fs.readFileSync('src/'+f,'utf8').split('\\n').length + ' lines'));
`);
보안·프라이버시 트레이드오프
| 장치 | 기본값 | 실무 함의 |
|---|---|---|
| 로컬 전용 | 텔레메트리·클라우드 동기화 없음. SQLite는 홈 디렉터리 | “컨텍스트 SaaS”가 아니라 온디바이스 계층. ELv2와도 정합 |
| 권한 deny/allow | Claude Code settings 형식을 전 플랫폼이 읽음. deny > allow | sudo·rm -rf /*·.env 거부가 샌드박스 실행에도 적용 |
| 프로젝트 경계 | ctx_execute_file 워크스페이스 밖 거부 |
호스트가 막은 경로를 MCP로 우회하던 #852 차단. 실행 도구 승인은 여전히 “임의 코드 승인” |
| fetch hardening | http(s)만, IMDS/링크로컬 차단. 루프백·RFC1918은 기본 허용 | 공유 CI면 CTX_FETCH_STRICT=1 |
| 세션 DB 레닥션 | MCP tool_input의 token/password/api_key 등 → [REDACTED] |
완전 비밀 관리가 아님. 디스크에 세션이 남는다는 사실 자체를 정책에 넣을 것 |
CONTEXT_MODE_DIR |
어댑터 기본. absolute path만 | Codex 등 쓰기 불가 홈일 때 오버라이드 |
도입 판단 체크리스트
| 상황 | 추천 | 이유 |
|---|---|---|
| Claude Code / OpenCode 중심, 장시간 에이전트 세션 | 적극 도입 | Full 세션 + 자동 라우팅. 체감 ROI가 가장 큼 |
| Cursor만 사용 | 도입하되 기대치 조정 | 도구 캡처·preToolUse는 됨. 압축 후 복원은 아직 Partial. Marketplace 대기 |
| Zed / Antigravity IDE만 | 파일럿 | MCP 도구는 쓰이지만 강제력 ~60%. 한 번의 비라우팅 curl이 절감을 날림 |
| 호스팅형 “팀 컨텍스트 서비스”로 재판매 | 불가(ELv2) | managed service 제공 금지. 사내 개발자 워크스테이션/CI 로컬은 일반적 사용 범위 |
| 이미 Headroom CCR을 씀 | 계층을 나눠 검토 | 중복이 아니라 보완 가능. 관측·디버깅 경로를 하나로 정리할 것 |
| Linux CI Node 20 | Node 22.5+ 또는 Bun으로 올려야 함 | 설치 스크립트가 막아 줌. “조용히 깨짐”보다 나음 |
한계와 남는 질문
- 라이선스: ELv2는 “오픈소스(OSI)”가 아니다. 소스 공개(source-available)다. 사내 법무·공급망 정책에 Elastic-2.0을 올릴 것. GitHub API의 NOASSERTION은 SPDX 미매핑일 뿐 LICENSE 파일과 모순되지 않는다.
- 플랫폼 파편: 17(+OpenClaw) 지원은 강점이자 유지비. Cursor sessionStart, Codex updatedInput, Kiro agentSpawn 등 “문서엔 있는데 런타임엔 없는” 훅이 계속 생긴다.
ctx_doctor를 배포 게이트에 넣는 편이 안전하다. - 벤치마크 소유권: 98%는 프로젝트 fixture 기준. 팀의 실제 MCP 구성(Jira/Slack/Notion 폭주 세션 등)에서는
CONTEXT_MODE_EXTERNAL_MCP_NUDGE_EVERY(기본 10) 같은 가이던스 재주입이 더 중요해진다. - 실행 신뢰 경계: 샌드박스는 “대화 오염 방지”이지 완전한 OS 샌드박스가 아니다. 승인 UI가 도구 인자 내부를 못 보는 MCP 특성상, 프로젝트 경계 가드는 방어 심층일 뿐이다.
- 버스 팩터·플러그인 리뷰: 빠른 성장 + 단일 메인테이너 중심. Cursor Marketplace 승인 전엔 로컬 플러그인 경로 운영 비용을 팀에 명시할 것.
정리
Context Mode가 푸는 문제는 “모델이 말을 너무 길게 한다”가 아니라 “도구가 대화를 먼저 먹는다”다. MCP 샌드박스로 출력을 가두고, FTS5로 세션·지식을 값싸게 붙들고, 훅으로 17개 클라이언트에 같은 라우팅을 강제한다. Headroom 같은 CCR 프록시와는 계층이 달라 대체재가 아니라 이웃이다. npm 1.0.169·별 2.7만·ELv2·Node≥22.5(또는 Bun)라는 조건만 팀 스택에 맞다면, Claude Code/OpenCode 장시간 세션부터 붙여 볼 가치가 충분하다. 붙인 뒤에는 ctx stats 숫자로 ROI를 재고, 훅이 꺼진 플랫폼에서는 절감률이 반토막 난다는 점만 기억하면 된다.