Claude Code LSP 설정 완전 가이드 — TypeScript·Python 언어 서버 5단계 연동

목차

Claude Code LSP 설정은 프로젝트의 언어 서버를 Claude Code에 연결해서 코드 인텔리전스를 강화하는 작업이다. LSP(Language Server Protocol)가 연동되면 Claude Code가 타입 정보, 심볼 참조, 정의 위치를 직접 파악한다. 파일을 하나하나 읽어가며 컨텍스트를 수집하는 대신 언어 서버의 인덱스를 그대로 쓰기 때문에 토큰 소비가 줄고, 응답 정확도는 올라간다.

TypeScript 프로젝트와 Python 프로젝트는 언어 서버의 구조가 다르다. tsserver는 tsconfig.json 기반으로 프로젝트 경계를 잡고, Python 쪽은 Pyright나 Pylsp가 pyrightconfig.json 또는 pyproject.toml을 기준으로 동작한다. 같은 Claude Code LSP 설정이라도 언어별로 잡아야 할 옵션이 다르고, 토큰 최적화 전략도 갈린다. 이 글은 두 언어의 설정 차이를 비교하고, 프로젝트 규모에 따른 최적화 방법을 정리한다.

LSP가 Claude Code에서 하는 일

LSP는 원래 VS Code 같은 에디터와 언어 서버 사이의 통신 프로토콜이다. Microsoft가 2016년에 공개했고, 지금은 거의 모든 에디터가 지원한다. Claude Code도 이 프로토콜을 통해 언어 서버와 통신한다.

LSP 없이 동작하는 경우

LSP가 연결되지 않으면 Claude Code는 파일 시스템을 직접 탐색한다. grep이나 ripgrep으로 심볼을 찾고, 파일을 열어서 컨텍스트를 파악한다. 이 방식은 동작은 하지만 비용이 크다.

  • 타입 정보를 알 수 없어서 추론에 의존
  • 심볼의 정의 위치를 찾으려면 여러 파일을 읽어야 함
  • 읽은 파일 내용이 전부 토큰으로 소비됨

LSP가 연결된 경우

lsp-connected-data-flow

언어 서버가 이미 프로젝트 전체를 인덱싱해 둔 상태이므로, Claude Code는 textDocument/definition, textDocument/references, textDocument/hover 같은 LSP 요청으로 필요한 정보만 가져온다. 파일 전체를 읽지 않아도 해당 심볼의 타입 시그니처와 위치를 바로 알 수 있다.

LSP 프로토콜 기본 동작
LSP는 JSON-RPC 기반 프로토콜이다. 클라이언트(Claude Code)가 요청을 보내면 서버(tsserver, Pyright 등)가 응답한다. 통신은 stdin/stdout 또는 TCP 소켓으로 이루어진다.
이 차이가 토큰 사용량에 미치는 영향은 뒤에서 수치로 비교한다.

TypeScript 프로젝트 LSP 연동

typescript-lsp-integration

TypeScript의 언어 서버는 tsserver다. typescript 패키지에 포함되어 있어서 별도 설치가 필요 없다. node_modules/.bin/tsserver로 실행되거나, 글로벌 설치된 TypeScript가 제공하는 서버를 쓴다.

tsconfig.json 설정 확인

Claude Code가 tsserver를 제대로 활용하려면 tsconfig.json이 프로젝트 루트에 있어야 한다. 없으면 tsserver가 프로젝트 경계를 인식하지 못하고, 모든 .ts 파일을 개별 스크립트로 취급한다.

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "strict": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "declaration": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist", "**/*.test.ts"]
}

includeexclude 설정이 중요하다. include 범위가 넓으면 tsserver가 인덱싱할 파일이 많아져 초기화가 느려진다. 테스트 파일이나 빌드 결과물은 exclude로 빼는 게 좋다.

Claude Code에서 TypeScript LSP 활성화

Claude Code의 설정 파일(.claude/settings.json 또는 프로젝트 루트의 .claude/settings.local.json)에서 LSP 관련 옵션을 지정한다.

{
  "lsp": {
    "typescript": {
      "enabled": true,
      "command": "typescript-language-server",
      "args": ["--stdio"],
      "initializationOptions": {
        "preferences": {
          "includeInlayParameterNameHints": "all",
          "includeInlayVariableTypeHints": true
        }
      }
    }
  }
}

typescript-language-server는 tsserver를 래핑하는 LSP 호환 서버다. tsserver 자체는 LSP 프로토콜을 직접 구현하지 않고 자체 프로토콜을 쓰기 때문에, 이 래퍼가 중간에서 변환 역할을 한다.

typescript-language-server 설치
`npm install -g typescript-language-server typescript` 명령으로 글로벌 설치한다. 프로젝트 로컬에 TypeScript가 설치되어 있으면 그 버전을 우선 사용한다.
### 모노레포 환경 주의점

모노레포에서는 tsconfig.json이 여러 개다. 루트에 tsconfig.base.json이 있고 각 패키지에 tsconfig.json이 있는 구조. tsserver는 열린 파일의 위치에서 가장 가까운 tsconfig.json을 자동으로 찾는다. Claude Code가 여러 패키지를 넘나들며 작업할 때 프로젝트 레퍼런스(references 필드)가 설정되어 있지 않으면 패키지 간 타입 참조가 끊길 수 있다.

{
  "references": [
    { "path": "../shared" },
    { "path": "../api-types" }
  ]
}

Python 프로젝트 LSP 연동

Python 언어 서버는 선택지가 둘이다. Pyright와 Pylsp(Python LSP Server). 성격이 다르다.

항목PyrightPylsp
개발사MicrosoftPython LSP 커뮤니티
타입 체크엄격한 정적 타입 분석선택적 (mypy 플러그인)
속도빠름 (Node.js 기반)상대적으로 느림 (Python 기반)
설정 파일pyrightconfig.jsonpyproject.toml 또는 설정 파일
플러그인없음rope, mypy, flake8 등

Pyright 설정

Pyright는 basedpyright 또는 pyright 패키지로 설치한다. Claude Code에서 연동하는 설정은 다음과 같다.

{
  "lsp": {
    "python": {
      "enabled": true,
      "command": "pyright-langserver",
      "args": ["--stdio"],
      "rootPatterns": ["pyproject.toml", "setup.py", "pyrightconfig.json"]
    }
  }
}

프로젝트 루트에 pyrightconfig.json을 두면 Pyright의 분석 범위와 엄격도를 제어할 수 있다.

{
  "include": ["src"],
  "exclude": ["**/node_modules", "**/__pycache__", "**/migrations"],
  "pythonVersion": "3.12",
  "pythonPlatform": "Linux",
  "typeCheckingMode": "basic",
  "reportMissingImports": true,
  "reportMissingTypeStubs": false
}

typeCheckingMode"off", "basic", "standard", "strict" 네 단계다. Claude Code와 함께 쓸 때는 "basic"이면 충분하다. "strict"로 올리면 서드파티 라이브러리의 타입 스텁 누락 경고가 쏟아져서 노이즈가 된다.

Pylsp 설정

Pylsp는 플러그인 생태계가 강점이다. pip install python-lsp-server로 설치하고, 플러그인을 추가로 넣는다.

pip install python-lsp-server[all]
pip install pylsp-mypy pylsp-rope

Claude Code 설정에서 Pylsp를 연결하는 방법:

{
  "lsp": {
    "python": {
      "enabled": true,
      "command": "pylsp",
      "args": [],
      "settings": {
        "pylsp": {
          "plugins": {
            "pycodestyle": { "enabled": false },
            "pyflakes": { "enabled": true },
            "pylsp_mypy": { "enabled": true, "live_mode": false }
          }
        }
      }
    }
  }
}
Pylsp mypy 플러그인 성능 주의
`pylsp_mypy`의 `live_mode`를 `true`로 설정하면 파일 변경 시마다 mypy가 돌아간다. 대규모 프로젝트에서는 응답이 수 초씩 늦어질 수 있다. `live_mode: false`로 두고 저장 시에만 실행되게 하는 편이 낫다.
## TypeScript vs Python LSP 설정 상세 비교

같은 Claude Code LSP 설정이라도 언어에 따라 체감이 다르다. 핵심 차이를 항목별로 정리한다.

비교 항목TypeScript (tsserver)Python (Pyright)Python (Pylsp)
초기화 속도중간 (프로젝트 크기 비례)빠름느림
타입 추론 정밀도높음 (TS 자체가 정적 타입)높음중간 (mypy 의존)
Go to Definition정확정확대체로 정확
Find References정확정확정확도 낮을 수 있음
자동완성 품질높음높음중간
메모리 사용높음 (대규모 시 1GB+)중간낮음
설정 복잡도낮음낮음높음 (플러그인 조합)

타입 정보의 질이 토큰에 미치는 영향

TypeScript는 모든 심볼에 타입 정보가 붙는다. tsserver가 hover 요청에 대해 돌려주는 응답에는 함수 시그니처, 제네릭 파라미터, 반환 타입이 전부 포함된다. Claude Code가 이 정보를 받으면 해당 함수를 사용하는 파일을 추가로 읽지 않아도 된다.

Python은 동적 타입 언어라 타입 정보가 불완전할 수 있다. 타입 힌트를 쓰지 않은 코드베이스에서는 Pyright도 Unknown 타입을 돌려보낸다. 이 경우 Claude Code가 추가 컨텍스트를 수집하기 위해 관련 파일을 더 읽게 되고, 토큰 사용량이 늘어난다.

타입 힌트를 꼼꼼히 달아둔 Python 프로젝트와 그렇지 않은 프로젝트 사이에 Claude Code의 토큰 소비 차이가 난다. 타입 힌트 커버리지가 높을수록 LSP가 제공하는 정보가 풍부해지고, Claude Code가 파일을 추가로 읽을 필요가 줄어든다.

모노레포 vs 단일 프로젝트

TypeScript 모노레포는 프로젝트 레퍼런스만 잘 잡아두면 tsserver가 패키지 간 의존성을 파악한다. Python 모노레포는 상황이 다르다. Pyright의 extraPaths 설정으로 다른 패키지의 소스 경로를 직접 알려줘야 한다.

{
  "extraPaths": ["../shared/src", "../utils/src"],
  "executionEnvironments": [
    {
      "root": "src",
      "pythonVersion": "3.12",
      "extraPaths": ["../shared/src"]
    }
  ]
}
executionEnvironments 활용
Pyright의 `executionEnvironments`는 프로젝트 내 하위 디렉터리별로 Python 버전과 경로를 다르게 설정할 수 있다. Lambda 함수(Python 3.9)와 메인 서버(Python 3.12)가 같은 레포에 있을 때 유용하다.
## 토큰 사용량 최적화 전략

Claude Code LSP 설정의 실질적 목적은 토큰 절약이다. LSP를 켜는 것만으로도 차이가 나지만, 세부 설정을 조정하면 효과가 더 커진다.

exclude 패턴 최적화

언어 서버가 인덱싱하는 파일 범위를 줄이면 두 가지 효과가 있다. 첫째, 서버 초기화가 빨라진다. 둘째, Claude Code가 LSP를 통해 받는 심볼 목록에 노이즈가 줄어든다.

TypeScript에서 자주 제외하는 패턴:

{
  "exclude": [
    "node_modules",
    "dist",
    "build",
    ".next",
    "coverage",
    "**/*.test.ts",
    "**/*.spec.ts",
    "**/*.stories.tsx",
    "e2e/**"
  ]
}

Python에서 자주 제외하는 패턴:

{
  "exclude": [
    "**/node_modules",
    "**/__pycache__",
    "**/migrations",
    "**/.venv",
    "**/dist",
    "tests/**",
    "scripts/**"
  ]
}

테스트 파일을 제외할지 여부는 상황에 따라 다르다. Claude Code에게 테스트 작성을 요청할 일이 많다면 테스트 디렉터리는 포함시켜야 한다. 반대로 프로덕션 코드 수정이 주 작업이면 제외하는 편이 토큰을 아낀다.

LSP 기능 선택적 비활성화

언어 서버가 제공하는 기능 중 Claude Code가 실제로 쓰는 것은 일부다. 쓰지 않는 기능을 끄면 서버 부하와 응답 시간이 줄어든다.

{
  "lsp": {
    "typescript": {
      "enabled": true,
      "command": "typescript-language-server",
      "args": ["--stdio"],
      "capabilities": {
        "textDocument": {
          "completion": { "dynamicRegistration": false },
          "formatting": { "dynamicRegistration": false },
          "codeAction": { "dynamicRegistration": false }
        }
      }
    }
  }
}

코드 포매팅(formatting)이나 코드 액션(codeAction)은 Claude Code가 직접 코드를 생성하므로 언어 서버에 위임할 필요가 없다. definition, references, hover 세 가지가 핵심이고, 나머지는 선택이다.

토큰 최적화 우선순위
효과가 큰 순서: (1) LSP 자체를 켜기 (2) exclude 패턴으로 인덱싱 범위 줄이기 (3) 불필요한 LSP 기능 비활성화. 1번만으로도 체감 차이가 크다. 2번과 3번은 대규모 프로젝트에서 의미가 있다.
## LSP 설정 트러블슈팅

설정을 마쳤는데 LSP가 동작하지 않는 경우가 있다. 흔한 원인과 해결 방법을 정리한다.

언어 서버가 시작되지 않는 경우

Claude Code 로그에서 LSP 관련 에러를 확인한다. claude --debug 모드로 실행하면 언어 서버의 stdin/stdout 통신 내역이 출력된다.

claude --debug 2>&1 | grep -i lsp

자주 나오는 에러:

  • spawn typescript-language-server ENOENT — 언어 서버가 PATH에 없다. which typescript-language-server로 경로 확인.
  • Connection to server got closed — 언어 서버가 크래시했다. node_modules가 손상되었거나 메모리 부족일 수 있다.
  • Initialization failedtsconfig.json이나 pyrightconfig.json에 문법 오류가 있다.

tsserver 메모리 문제

대규모 TypeScript 프로젝트에서 tsserver가 메모리를 과도하게 소비하면 OOM으로 죽는다. NODE_OPTIONS 환경변수로 힙 사이즈를 올릴 수 있다.

export NODE_OPTIONS="--max-old-space-size=4096"

근본적으로는 tsconfig.jsoninclude 범위를 줄이거나, 프로젝트 레퍼런스로 분할하는 게 맞다.

Pyright 가상환경 인식 문제

Pyright가 가상환경의 패키지를 못 찾는 경우가 흔하다. pyrightconfig.jsonvenvPathvenv를 명시한다.

{
  "venvPath": ".",
  "venv": ".venv"
}

또는 pyproject.toml[tool.pyright] 섹션에 넣어도 된다.

[tool.pyright]
venvPath = "."
venv = ".venv"
pythonVersion = "3.12"

Pyright가 이 설정을 읽으면 .venv/lib/python3.12/site-packages에서 패키지 타입 정보를 가져온다. 설정이 없으면 import requests에 빨간 줄이 뜨고, Claude Code도 해당 모듈의 타입 정보를 받지 못한다.

프로젝트 규모별 최적화 전략

모든 프로젝트에 같은 설정을 적용하면 안 된다. 규모에 따라 전략이 달라진다.

소규모 프로젝트 (파일 100개 미만)

LSP를 기본 설정으로 켜면 충분하다. exclude 패턴도 node_modulesdist 정도만 잡으면 된다. tsserver든 Pyright든 초기화가 1~2초면 끝나고, 메모리도 200~300MB 수준이다.

설정 파일 하나면 된다:

{
  "lsp": {
    "typescript": {
      "enabled": true,
      "command": "typescript-language-server",
      "args": ["--stdio"]
    }
  }
}

중규모 프로젝트 (파일 100~1000개)

exclude 패턴을 신경 써야 한다. 테스트 파일, 스토리북, e2e 디렉터리를 상황에 맞게 제외한다. TypeScript의 경우 skipLibCheck: truetsconfig.json에 넣으면 node_modules.d.ts 파일 검사를 건너뛰어서 tsserver가 가벼워진다.

{
  "compilerOptions": {
    "skipLibCheck": true
  }
}

대규모 프로젝트 (파일 1000개 이상)

프로젝트 레퍼런스로 분할하는 게 사실상 필수다. 단일 tsserver 인스턴스가 파일 수천 개를 처리하면 초기화에 10초 이상, 메모리 1GB 이상을 쓴다.

Python 대규모 프로젝트에서는 Pyright의 typeCheckingMode"off"로 두고, definitionreferences 기능만 쓰는 방법도 있다. 타입 체크는 CI에서 하고, Claude Code에서는 네비게이션 기능만 활용하는 전략이다.

graph TD
    A[프로젝트 규모 판단] --> B{파일 100개 미만?}
    B -->|Yes| C[기본 설정으로 충분]
    B -->|No| D{파일 1000개 미만?}
    D -->|Yes| E[exclude 패턴 최적화 + skipLibCheck]
    D -->|No| F[프로젝트 분할 + 기능 선택적 비활성화]
    F --> G[TypeScript: 프로젝트 레퍼런스]
    F --> H[Python: typeCheckingMode off + 네비게이션만]

언어 서버 선택 기준과 다음 단계

설정 파일 위치 주의
`.claude/settings.json`은 전역 설정이고, `.claude/settings.local.json`은 프로젝트별 로컬 설정이다. LSP 설정은 프로젝트마다 다를 수 있으므로 `.claude/settings.local.json`에 넣는 편이 관리하기 편하다. 이 파일은 `.gitignore`에 추가해서 개인 설정이 레포에 들어가지 않게 한다.
Claude Code LSP 설정에서 TypeScript와 Python의 선택 기준을 정리하면 이렇다. TypeScript 프로젝트는 tsserver 외에 선택지가 없고, 설정도 단순하다. `tsconfig.json`만 잘 잡아두면 된다. Python 프로젝트는 타입 힌트 커버리지가 높으면 Pyright, 린팅과 리팩토링 기능이 더 필요하면 Pylsp를 선택한다. 두 언어 모두 `exclude` 패턴과 프로젝트 분할이 토큰 최적화의 핵심이다.

LSP 설정이 잡히면 다음 단계로 Claude Code의 커스텀 슬래시 커맨드를 만들어볼 만하다. 자주 쓰는 작업 — 타입 에러 일괄 수정, 테스트 파일 생성, 리팩토링 패턴 적용 — 을 커맨드로 등록하면 LSP 정보와 결합해서 더 정확한 결과가 나온다. MCP 서버를 직접 붙여서 외부 API 문서나 DB 스키마를 Claude Code에 제공하는 것도 LSP와 시너지가 크다. 프로젝트의 데이터 모델을 MCP 리소스로 노출하면 Claude Code가 타입 정보와 도메인 정보를 동시에 참조할 수 있다.

이 글 공유하기