Give GitHub Copilot CLI real code intelligence with language servers

mariuz1 pts0 comments

Give GitHub Copilot CLI real code intelligence with language servers - The GitHub Blog

Try GitHub Copilot CLI

Attend GitHub Universe

Search

Bruno Borges·@brunoborges

June 10, 2026

5 minutes

Share:

Ever watched GitHub Copilot CLI extract a JAR file to a temporary directory, grep through .class files, and piece together an API signature from raw bytecode? The agent is resourceful, but without a language server, that’s the best it can do.

The Language Server Protocol (LSP) is the standard that powers go to definition, find references, and type resolution in editors like VS Code. It works just as well in the terminal. The LSP Setup skill automates the installation and configuration of LSP servers for Copilot CLI, so the agent gets precise, structured answers about your code instead of relying on text search heuristics.

In this post, you’ll learn how the skill works under the hood, see the configuration format it generates, and get set up for any of the 14 languages it supports today.

The problem: heuristic code understanding

Without an LSP server, the agent in GitHub Copilot CLI reverse-engineers API information through text search and binary extraction. For a Java project, that might look like:

# Find the dependency JAR<br>find ~/.m2/repository -name "*httpclient*.jar"

# Extract it to a temp directory<br>mkdir /tmp/httpclient && cd /tmp/httpclient<br>jar xf ~/.m2/repository/org/apache/httpcomponents/httpclient/4.5.14/httpclient-4.5.14.jar

# Search extracted class files for a method<br>grep -r "execute" --include="*.class" .

For Python, the agent might cat files inside site-packages. For TypeScript, it walks node_modules. These text-based approaches work for simple cases, but they&rsquo;re doing pattern-matching over raw text rather than true semantic analysis, so they miss generics, overloads, and transitive types, and can&rsquo;t see compiled bytecode at all. That&rsquo;s exactly the gap a language server close.

An LSP server solves this structurally. When the agent sends a textDocument/definition request for a symbol, the language server returns the exact source location, fully resolved type, and signature.

What is an agent skill?

Agent skill is a reusable instruction set that extends what an AI coding agent can do. Skills are defined in Markdown files with YAML frontmatter and follow a standard structure: trigger descriptions, step-by-step workflows, reference data, and behavioral constraints.

The LSP Setup skill uses this structure to guide the agent through a multi-step installation process, detecting the operating system, choosing the right package manager, writing valid configuration, and verifying the result.

How the LSP Setup skill works

When triggered, the skill executes a seven-step workflow:

1. Language selection

The agent uses ask_user with a set of choices to determine which language the user needs LSP support for. This drives all subsequent steps.

2. Operating system detection

The agent runs uname -s (or checks $env:OS / %OS% on Windows) to determine the target platform. Install commands vary by operating system. For example, brew install jdtls on macOS versus downloading from eclipse.org on Linux.

3. LSP server lookup

The skill includes a reference file (references/lsp-servers.md) with curated data for 14 languages: install commands per operating system, binary names, and ready-to-use config snippets. The agent reads this file and selects the matching entry.

4. Configuration scope

The agent asks whether the config should be:

User-level : ~/.copilot/lsp-config.json—applies to all repositories

Repository-level : lsp.json at the repository root or .github/lsp.json—scoped to a single project

Repository-level configuration takes precedence when both exist.

5. Installation

The agent runs the appropriate install command. For example:

# TypeScript on any OS<br>npm install -g typescript typescript-language-server

# Java on macOS<br>brew install jdtls

# Rust on any OS<br>rustup component add rust-analyzer

6. Configuration

The agent writes or merges an entry into the chosen config file. The format uses a lspServers object where each key is a server identifier:

"lspServers": {<br>"java": {<br>"command": "jdtls",<br>"args": [],<br>"fileExtensions": {<br>".java": "java"

Key rules the skill enforces:

command must be on $PATH or an absolute path

args typically includes "--stdio" for standard I/O transport (some servers like jdtls handle this internally)

fileExtensions maps each extension (with leading dot) to a language identifier

Existing entries in the config file are preserved — the agent merges, never overwrites

7. Verification

The agent runs which (or where.exe on Windows) to confirm the server is accessible, then validates the config file is well-formed JSON.

Supported languages

The skill comes with a set of predefined language servers for several programming languages. If the coding agent faces one that it is not mapped out already, it will search for an appropriate server...

agent language server skill github copilot

Related Articles