Skip to main content
skill CX Codex

lsp-format-code — Claude Code skill for code formatting

Formats an entire source file or a selected line range through a language server. Use it to tidy generated code or apply the project's formatting rules before a commit.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add blackwell-systems/agent-lsp --skill lsp-format-code -a claude-code
Open on GitHub

What lsp-format-code does

The lsp-format-code skill asks the language server to format code using the formatter associated with that language. Its documented examples cover Go, TypeScript, JavaScript, Rust, Python, and C/C++, with tools such as gofmt, prettier, rustfmt, black, and clang-format. These formatters do not need separate installation on PATH for the described workflow.

The workflow opens the target document, requests edits for either the full file or a chosen line range, and passes the returned TextEdit list to mcp__lsp__apply_edit. Formatting requests alone do not write changes to disk. A diagnostics check can follow; if formatting support is unavailable, the skill stops that path and recommends invoking the formatter directly.

The agent-lsp MCP server must be available and expose document formatting support. Range formatting relies on the additional documentRangeFormattingProvider capability, so a server that supports whole-file formatting may still lack range support. If formatting introduces diagnostic errors, the instructions say to report them before committing.

What it helps with

  • Apply language-specific formatting to a complete source file
  • Clean up indentation and spacing in generated code
  • Format only the lines containing a function
  • Address formatter-fixable style violations before a commit
  • Check diagnostics after applying formatting edits

Example prompts for the agent

  • Format src/main.go through the language server and check the file diagnostics afterward.
  • Reformat the function in src/app.ts using only its line range.
  • Format every changed file before committing and report any file whose language server lacks formatting support.

How to install lsp-format-code

1Skills CLI (Vercel)

npx skills add blackwell-systems/agent-lsp --skill lsp-format-code -a claude-code

2Manually: put the files in place

~/.claude/skills/lsp-format-code/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/lsp-format-code/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about lsp-format-code

How do I install lsp-format-code in Claude Code?

Run npx skills add blackwell-systems/agent-lsp --skill lsp-format-code -a claude-code. The installed skill file is at ~/.claude/skills/lsp-format-code/SKILL.md.

What does the lsp-format-code skill do?

It requests formatting edits from a language server for a complete document or a selected range, applies the returned edits through mcp__lsp__apply_edit, and can check diagnostics afterward.

Does lsp-format-code need a formatter installed on PATH?

The documented workflow does not require separate PATH installations of the listed formatters. It does require the agent-lsp MCP server and document-formatting support from the language server.

Source text

SKILL.md · MIT
---
name: lsp-format-code
description: Format a file or selection using the language server's formatter. Use before committing to apply consistent style, or after generating code to clean up indentation and spacing. Supports full-file and range-based formatting.
argument-hint: "[file-path] [optional: start_line-end_line]"
user-invocable: true
allowed-tools: mcp__lsp__open_document mcp__lsp__format_document mcp__lsp__format_range mcp__lsp__apply_edit mcp__lsp__get_diagnostics mcp__lsp__get_server_capabilities
license: MIT
compatibility: Requires the agent-lsp MCP server (github.com/blackwell-systems/agent-lsp)
metadata:
  required-capabilities: documentFormattingProvider
  optional-capabilities: documentRangeFormattingProvider
---

> Requires the agent-lsp MCP server.

# lsp-format-code

Format a file or selection using the language server's formatter — the same
formatting engine your IDE uses. Applies language-specific rules (gofmt, prettier,
rustfmt, black) without requiring those tools to be on PATH separately.

## When to use

- Before committing: ensure consistent style across edited files
- After generating code: clean up AI-generated indentation and spacing
- After a refactor that shifted indentation levels
- When a linter flags style violations fixable by the formatter

Use `/lsp-safe-edit` instead when you are making a logic change and want
before/after diagnostic comparison alongside the edit.

---

## Workflow

### Step 1 — Check formatting is supported (optional)

If unsure whether the language server supports formatting for this file, check
capabilities first:

```
mcp__lsp__get_server_capabilities({ "file_path": "<file>" })
```

Look for `documentFormattingProvider` (full-file) and
`documentRangeFormattingProvider` (range). If neither is present, the server
does not support formatting — stop and report.

Skip this step if you know the language supports formatting (Go, TypeScript,
Rust, Python all do via their standard servers).

### Step 2 — Open the file

```
mcp__lsp__open_document({ "file_path": "/abs/path/to/file.go", "language_id": "go" })
```

### Step 3 — Request formatting edits

**Full file:**
```
mcp__lsp__format_document({ "file_path": "/abs/path/to/file.go" })
```

**Selection only:**
```
mcp__lsp__format_range({
  "file_path": "/abs/path/to/file.go",
  "start_line": <N>,
  "end_line": <M>
})
```

Both return `TextEdit[]` — a list of replacements to apply. They do **not**
write to disk. If the list is empty, the file is already correctly formatted.

### Step 4 — Apply the edits

Pass the `TextEdit[]` from Step 3 to `apply_edit`:

```
mcp__lsp__apply_edit({ "workspace_edit": <TextEdit[] from Step 3> })
```

This writes the formatting changes to disk.

### Step 5 — Verify (optional but recommended)

Call `get_diagnostics` to confirm formatting did not introduce any errors:

```
mcp__lsp__get_diagnostics({ "file_path": "/abs/path/to/file.go" })
```

Formatting should never introduce errors — if it does, report immediately
without committing.

---

## Output format

```
## Format result: <filename>

Changes applied: N edits
Lines affected: <range or "whole file">
Formatter: <gopls | typescript-language-server | rust-analyzer | ...>

Status: FORMATTED ✓
```

If no edits were returned:
```
Status: ALREADY FORMATTED — no changes needed
```

If formatting is not supported:
```
Status: NOT SUPPORTED — <server> does not expose documentFormattingProvider
Fallback: run the formatter directly (gofmt, prettier, rustfmt, etc.)
```

---

## Multi-file formatting

For formatting multiple files (e.g. all files changed in a PR):

1. Call `format_document` for each file — these can run in parallel.
2. Collect all `TextEdit[]` responses.
3. Apply each file's edits via `apply_edit` sequentially.
4. Report total edits across all files.

Do not apply edits from multiple files in a single `apply_edit` call —
apply per-file to keep changes scoped and reversible.

---

## Decision guide

| Situation | Action |
|-----------|--------|
| Formatting a whole file before commit | `format_document` → `apply_edit` |
| Formatting only generated code in a function | `format_range` with the function's line range |
| Empty `TextEdit[]` returned | File is already formatted — no action needed |
| Server doesn't support formatting | Report and suggest running CLI formatter directly |
| Formatting introduces diagnostics | Do not commit — report immediately |
| Formatting a Go file in a workspace repo | Ensure `GOWORK=off` is set if running via shell fallback |

---

## Language notes

| Language | Formatter | Server |
|----------|-----------|--------|
| Go | `gofmt` (via gopls) | `gopls` |
| TypeScript / JavaScript | `prettier` or built-in (via typescript-language-server) | `typescript-language-server` |
| Rust | `rustfmt` (via rust-analyzer) | `rust-analyzer` |
| Python | `black` or `autopep8` (via pyright/pylsp) | `pyright-langserver` or `pylsp` |
| C / C++ | `clang-format` (via clangd) | `clangd` |

The language server delegates to the language's standard formatter — results
match what your IDE would produce.

© blackwell-systems · MIT · blackwell-systems/agent-lsp

Similar skills

All skills for Agent setup: memory, context, orchestration →

From the same set25

lsp-inspect Runs a deep code quality audit on files or directories using LSP data. Flags dead symbols, swallowed errors, and concurrency flaws before release. CX Codex +1 ★ 165repo stars lsp-implement Find concrete types that implement an interface or extend an abstract type. Run it before changing a base type to see which implementations the change may affect. CX Codex +1 ★ 165repo stars lsp-impact Maps every caller, supertype and subtype, and reference count for a symbol or file before you touch it. Built for refactors and deletions. CX Codex +1 ★ 165repo stars lsp-generate Triggers language server code generation for interface stubs, test skeletons, and missing methods. Useful when scaffolding new types or missing symbols. CX Codex +1 ★ 165repo stars lsp-fix-all Walks every diagnostic in a file and applies the quick-fixes your language server offers. Handy when errors and warnings have piled up before you start new work. CX Codex +1 ★ 165repo stars lsp-extract-function Extracts selected code blocks into named functions via LSP code actions or manual AST fallback. Validates scopes, arguments, and compilation diagnostics. CX Codex +1 ★ 165repo stars lsp-explore Inspect a symbol’s definition, type details, implementations, callers, and references in one report. Useful when you’re finding your way around an unfamiliar codebase. CX Codex +1 ★ 165repo stars lsp-edit-symbol Changes a function, type or variable by name when you don't know the file or position. Runs on the agent-lsp MCP server. CX Codex +1 ★ 165repo stars

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor