目次
2026 年 3 月、AI 駆動開発情報のコムテ氏(@commte)が X で**「Claude Code の LSP、地味に強い。実際に計測してみた」**と公開した。
LSP(Language Server Protocol)を有効にすると、Claude Code が IDE のようにコードの意味を理解した上で検索してくれるようになる。
本稿はこの LSP 機能の概要、効果、そして設定方法を解説する。
LSP とは
LSP(Language Server Protocol)は、プログラミング言語のサポートを標準化するためのプロトコルだ。
従来の Claude Code の検索
普段 Claude Code がコードを検索するとき、内部ではripgrep(テキスト検索)が使われている。
- 速い - 10-13ms で検索完了
- 文字列一致 - あくまで文字列の一致でしかない
- ノイズが多い - 無関係な一致も拾う
LSP を有効にすると
LSP を有効にすると、Claude Code が IDE のようにコードの意味を理解した上で検索してくれるようになる。
- 意味理解 - スコープを理解して検索
- 精度高い - 同一変数だけを返す
- 逆引き可能 - 呼び出し元の逆引きが可能
検証結果
Next.js + TypeScript のプロジェクト(約 560 ファイル)で、同じ検索タスクを ripgrep と LSP の両方で実行して比較した。
1. 汎用変数名の参照検索
handler.ts 内の result という変数の参照箇所を探すタスク。
| 手法 | 結果 | ファイル数 |
|---|---|---|
| ripgrep | 734 件 | 63 ファイル |
| LSP | 3 件 | 1 ファイル |
ripgrep はプロジェクト全体から result という文字列をすべて拾う。
LSP はスコープを理解しているので、同じファイル内の同一変数だけを返す。
731 件の差は全部ノイズだ。
2. 呼び出し元の逆引き
createLogger を呼んでいる関数を探すタスク。
| 手法 | 結果 | 詳細 |
|---|---|---|
| ripgrep | 150 件 | import か呼び出しか区別できない |
| LSP | 71 件 | 呼び出し元を関数名付きで返却 |
ripgrep では原理的にできない逆引きが、LSP なら可能だ。
3. 型情報の取得
withLog でラップされた関数の型シグネチャを取得するタスク。
| 手法 | 結果 |
|---|---|
| ripgrep | withLog(...) というテキストが返るだけ |
| LSP | (_req: Request) => Promise<Response> ラッパー越しの型シグネチャを取得 |
ラッパーを通した後の実際の型シグネチャが返る。
ripgrep では withLog(handleChatRequestImpl, { ... }) というテキストしか得られず、具体的な型を知るには定義元を辿る必要がある。
LSP なら hover 1 回で完結する。
速度はどうか
| 手法 | 速度 |
|---|---|
| ripgrep | 10-13ms |
| LSP | やや遅い |
ripgrep が 10-13ms で、正直これで十分速い。
LSP の価値は速度ではなく**「精度」と「grep にはできない操作」**にある。
設定方法(TypeScript の場合)
ステップ 1: 言語サーバーのインストール
npm i -g typescript-language-server typescript
ステップ 2: Claude Code プラグインのインストール
claude plugin install typescript-lsp
ステップ 3: Claude Code の再起動
Claude Code を再起動する。
以上。どれもグローバル設定なので、一度やれば全プロジェクトで有効になる。
ENABLE_LSP_TOOL という環境変数の情報もあるが、現バージョンではプラグインをインストールするだけで動作することを確認済み。
注意点
1. LSP は deferred tool
LSP は deferred tool(遅延読み込み)のため、CLAUDE.md に指示を書いても Claude が Grep で済ませてしまう。
プロンプトで**「LSP で探して」**と明示すると、Claude が自動で LSP ツールを読み込んで使ってくれる。
2. インデックスのずれ
ファイルを大量に変更した直後は LSP のインデックスがずれて、incomingCalls などでエラーが出ることがある。
少し待てば再インデックスされて復旧する。
普段の開発では気にならないレベルだ。
ripgrep では原理的にできないこと
1. 呼び出し元の特定
「createLogger を呼んでいる関数はどれか?」
ripgrep だと createLogger を含む行が返るだけ。
それが import 文なのか実際の呼び出しなのかは分からない。
ファイルを 1 つずつ開いて確認する必要がある。
LSP の incomingCalls なら、71 件の呼び出し元が関数名・行番号付きで 1 発で返ってくる。
2. 型情報の取得
withLog でラップした関数に hover すると、ラッパーを通した後の実際の型シグネチャが返る。
const handleChatRequest: (_req: Request) => Promise<Response>
ripgrep では withLog(handleChatRequestImpl, { ... }) というテキストしか得られず、具体的な型を知るには定義元を辿る必要がある。
LSP なら hover 1 回で完結する。
結論:入れていい
コムテ氏の結論は**「入れていい」**だ。
大規模プロジェクトほど効果が出そうだが、小規模でも目立ったデメリットはなかった。
LSP の価値は速度ではなく**「精度」と「grep にはできない操作」**にある。
設定は簡単で、一度設定すれば全プロジェクトで有効になる。
Claude Code を使っているなら、LSP の導入を検討する価値がある。
参考:
引用元・参考リンク
免責事項 — 掲載情報は執筆時点のものです。料金・機能は変更される場合があります。最新情報は各公式サイトをご確認ください。