Skip to main content
Glama
r-irbe

lean-lsp-mcp

by r-irbe

lean-lsp-mcp -- Standalone Lean 4 & C FFI Model Context Protocol Server

lean-lsp-mcp is an open-source, standalone Model Context Protocol (MCP) server providing AI coding agents (Claude Code, Cursor, Windsurf, Zed, Antigravity) with high-performance tools for Lean 4 formal verification, offline navigation, and C FFI inspection.

NB! Still pre-alpha!


Install

From npm (published bin lean-lsp-mcp / lean4-lsp-mcp):

npx lean4-lsp-mcp
# or
npm install -g lean4-lsp-mcp
lean-lsp-mcp

From a clone:

git clone https://github.com/r-irbe/lean4-lsp-mcp.git
cd lean4-lsp-mcp
npm install
npm run build
node dist/index.js

The server speaks MCP over stdio. Point your Lean 4 project at the process working directory (or set LEAN_PROJECT_ROOT); elan / lake should be on PATH.


Related MCP server: Sigil MCP Server

1. Key Capabilities

  1. Interactive Proof State (lean_plain_goal): Queries $/lean/plainGoal via persistent lake serve child processes, formatting proof goals directly into markdown without file pollution.

  2. Expected Term Types (lean_plain_term_goal): Queries $/lean/plainTermGoal for exact sub-term typing and implicit argument inspection.

  3. Sub-millisecond Offline Navigation (lean_jump_definition): Direct binary JSON parsing of pre-compiled .lake/build/ir/**/*.ilean files, returning instant symbol definitions without waiting for compiler elaboration.

  4. Module Dependency Hierarchy (lean_module_dag): Fast forward (imports) and reverse (importedBy) DAG traversal, determining blast radius before edits.

  5. Cross-Language C FFI Navigation (lean_c_ffi): Bidirectional resolution between Lean @[extern] declarations and human-authored C FFI implementations, plus automatic injection of lean --print-prefix headers into clangd.

  6. Code Action Harvesting (lean_code_actions): Retrieval of suggested Try this proof scripts from search tactics (exact?, simp?, grind?).


2. Architecture

+-----------------------------------------------------------------------------+
|                          lean-lsp-mcp ARCHITECTURE                          |
+-----------------------------------------------------------------------------+
|                                                                             |
|  [ AI Host ] (Claude Code / Cursor / Windsurf / Antigravity)                |
|       |                                                                     |
|  stdio JSON-RPC (MCP Protocol)                                              |
|       v                                                                     |
|  [ lean-lsp-mcp Server ]                                                    |
|    |-- Request Dispatcher & Cache Manager                                   |
|    |-- .ilean Zero-Latency Indexer (Sub-millisecond offline symbol lookup)  |
|    |-- Lake Server Process Manager (Persistent `lake serve` session)        |
|    |-- Clangd C FFI Sysroot Bridge (Injects `lean --print-prefix` headers)  |
|       |                                                                     |
|       +---> Lean 4 Toolchain (`lake serve` / `elan`)                        |
|       +---> Clangd Language Server (`clangd`)                               |
|       +---> Project Filesystem (`.lake/build/ir/**/*.ilean`, `.olean`)      |
|                                                                             |
+-----------------------------------------------------------------------------+

3. Tool Specifications

lean_plain_goal

  • Arguments:

    • filePath (string, required): Absolute or relative path to the .lean file.

    • line (number, 1-indexed): Cursor line position.

    • character (number, 1-indexed): Cursor column position.

  • Returns: Markdown-rendered proof state with open goals, hypotheses, and types.

lean_plain_term_goal

  • Arguments:

    • filePath (string, required)

    • line (number)

    • character (number)

  • Returns: Markdown-rendered expected term type at cursor position.

lean_jump_definition

  • Arguments:

    • symbol (string, required): Qualified symbol name (e.g. List.length).

    • sourceFile (string, optional): Context file for relative namespace resolution.

    • preferOfflineIlean (boolean, default true): Use sub-millisecond .ilean cache.

  • Returns: Target file path, line number, and character range.

lean_module_dag

  • Arguments:

    • moduleName (string, required): Dot-separated module name (e.g. Mathlib.Data.List).

    • direction (enum: "imports" | "importedBy", default "imports").

  • Returns: List of direct and transitive module dependencies.

lean_c_ffi

  • Arguments:

    • symbol (string, required): Declaration name or C function identifier.

    • action (enum: "jump_to_c" | "jump_to_lean" | "inspect_ir").

  • Returns: Target location or compiled C99 IR excerpt.


4. Configuration Across Agent Hosts

Prefer the published bin. After a local clone and npm run build, you can also use node dist/index.js.

Claude Code (~/.claude/claude_desktop_config.json or project .mcp.json)

{
  "mcpServers": {
    "lean-lsp": {
      "command": "npx",
      "args": ["-y", "lean4-lsp-mcp"],
      "env": {
        "PATH": "${HOME}/.elan/bin:/usr/bin:/bin"
      }
    }
  }
}

Cursor & Windsurf (.cursor/mcp.json)

{
  "mcpServers": {
    "lean-lsp": {
      "command": "lean-lsp-mcp"
    }
  }
}

From a clone, after npm run build:

{
  "mcpServers": {
    "lean-lsp": {
      "command": "node",
      "args": ["dist/index.js"]
    }
  }
}

Available Tools

5 tools
lean_c_ffi_inspectA

Cross-language C FFI inspector: Lean @[extern] declarations, C implementations, and Lean sysroot include flags

ParametersJSON Schema
NameRequiredDescriptionDefault
actionNoFFI inspection action (default: inspect)
externNameNoOptional Lean @[extern] identifier or C function name

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of behavioral disclosure. 'Inspector' implies a read-only, informational operation, and the listed artifacts show scope, but the description does not explain what each action returns, whether side effects occur, or how 'jump_to_c' behaves in a headless/agent context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no filler. Every phrase adds meaningful information about the tool's domain and scope.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a multi-action tool with no output schema and no annotations, so the description should clarify what the 'sysroot', 'inspect', and 'jump_to_c' actions actually produce or do. The enum names are suggestive, but the description does not explain return values or action semantics clearly enough for fully confident agent invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the input schema already documents both 'action' and 'externName' adequately. The description adds domain context for the tool's purpose but does not elaborate on parameter-specific behavior beyond what the enum and descriptions provide.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific operation ('inspector') and a precise resource domain: Lean @[extern] declarations, C implementations, and sysroot include flags. It clearly distinguishes this tool from the sibling Lean goal/symbol/module tools, which concern different aspects of the Lean environment.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context: use this when working with Lean's C FFI layer, extern declarations, or C implementation navigation. It does not explicitly name alternatives or when-not-to-use conditions, but the domain is specific enough that no exclusions are necessary.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

lean_goalA

Queries interactive Lean 4 tactic proof state at cursor position ($/lean/plainGoal)

ParametersJSON Schema
NameRequiredDescriptionDefault
colNo1-based column number
lineYes1-based line number
filePathYesAbsolute or relative path to the .lean file
characterNoSynonym for col

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full behavioral burden. 'Queries' implies a read-only operation and 'interactive proof state' indicates it depends on an active Lean session, which is useful. It does not disclose what the returned goal state looks like or whether the file must be open/saved, leaving some behavior implicit.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence with no filler. It front-loads the core action and resource, and the embedded LSP method adds precise context without extra length.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple query tool, the description covers the essential purpose and location semantics. However, with no output schema and no annotations, details about the return value and operational prerequisites (e.g., file must be open in a Lean session) are left unspecified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all four parameters. The description adds only the general notion of 'cursor position', which loosely ties filePath, line, and col/character together but does not add meaningful detail beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Queries') and names a precise resource: 'interactive Lean 4 tactic proof state at cursor position'. It also includes the LSP method identifier ($/lean/plainGoal), which adds precision. It does not explicitly contrast with the sibling lean_term_goal, though 'tactic proof state' implies a distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'at cursor position' conveys that the tool should be used when an agent needs the proof state at a particular location in a Lean file. However, it provides no explicit guidance on when to choose this tool over lean_term_goal or other siblings, and no exclusions are stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

lean_lookup_symbolA

Offline zero-latency symbol lookup and jump-to-definition via pre-compiled .ilean cache

ParametersJSON Schema
NameRequiredDescriptionDefault
symbolYesLean declaration name (e.g. RealQ.bellmanOp or BoundedRewardKernel)
preferOfflineIleanNoUse fast .ilean cache (default true)

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden. It discloses that the tool operates offline, uses a pre-compiled .ilean cache, and is optimized for zero-latency lookups, which are meaningful beyond the schema. It stops short of stating whether cache writes or refresh operations can occur, but for a lookup operation the read-only intent is reasonably clear.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single well-formed sentence that front-loads the primary action and then specifies the mechanism. There is no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter lookup tool with full schema descriptions, the description plus schema is largely sufficient for an agent to select and invoke it. It does not describe the return payload or cache-miss behavior, but the core selection and invocation context is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the parameter meanings are already fully documented. The description adds no additional semantics beyond reinforcing the cache behavior already reflected in preferOfflineIlean.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: symbol lookup and jump-to-definition, with the exact mechanism (.ilean cache). This is clearly distinct from sibling tools focused on goals, module hierarchy, or FFI inspection.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The intent is implied: use this when you need a fast offline symbol lookup or jump-to-definition. It does not explicitly state when to prefer or avoid sibling tools, so no exclusion guidance is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

lean_module_hierarchyB

Forward and reverse module import dependency hierarchy analysis

ParametersJSON Schema
NameRequiredDescriptionDefault
directionNoDirection of dependency traversal (default: both)
moduleNameYesFull module name (e.g. EASCI.ReinforcementLearning.Core)

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full disclosure burden. It does convey that traversal can be forward/reverse and that the subject is dependency hierarchy, but it does not say what the tool returns, whether dependencies are direct or transitive, or what 'analysis' produces. Some behavior is disclosed, but key traits are left implicit.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single compact phrase with no filler; the subject and directional scope are front-loaded. Every word contributes to the meaning, so it earns a top conciseness score.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema and no annotations, so the description needs to specify the result shape or behavioral outcome, but it only labels the operation as 'analysis'. For a tool that returns a hierarchy, the absence of any return/format or depth information leaves an agent without a clear model of what invoking it will produce.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already explains moduleName and direction values. The description adds the forward/reverse framing but no additional parameter semantics beyond the enum descriptions, matching the baseline for full schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description identifies the resource as module import dependency hierarchy and the key scope axis as forward/reverse, which is distinct from the sibling tools that target goals, symbols, and FFI inspection. It lacks a direct action verb like 'returns' or 'computes', so it is clear but not maximally explicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance or alternative routing is given. The intended use is inferable from the name and sibling list, but the description never states when to choose this over other Lean inspection tools or what the prerequisites are.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

lean_term_goalB

Queries expected term type under cursor ($/lean/plainTermGoal)

ParametersJSON Schema
NameRequiredDescriptionDefault
colNo1-based column number
lineYes1-based line number
filePathYesAbsolute or relative path to the .lean file
characterNoSynonym for col

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. The verb 'queries' implies a read-only operation, but nothing else is revealed—no mention of error cases, return format, or prerequisites. The tool's behavior depends on the file state, and the description offers no hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that states the purpose immediately and includes the protocol method in parentheses as supplementary info. There is no fluff or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description provides the core purpose but does not elaborate on return values or edge cases, and there is no output schema to fill that gap. For a simple query tool, it is minimally adequate but lacks richer context that could help an agent understand the tool's full behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

All four parameters are already documented in the schema with descriptions (e.g., column is '1-based column number', line is '1-based line number'). The tool description adds no parameter-specific meaning, but with 100% schema coverage, the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Queries') and a clear resource ('expected term type under cursor'), making the tool's function unambiguous. It also differentiates from siblings like lean_goal (queries goals) and lean_lookup_symbol (looks up symbols) by focusing on term type at a cursor position.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given on when to use this tool versus its siblings. The description does not mention any selection criteria, alternatives, or exclusions. An agent is left without context on when this tool is the right choice compared to lean_goal or others.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updatesv0.1.0
    • First observedlean_c_ffi_inspect
    • First observedlean_goal
    • First observedlean_lookup_symbol
    • First observedlean_module_hierarchy
    • First observedlean_term_goal

TDQS

A3.8/5.0

Scored across 5 tools

Disambiguation5/5

Each tool targets a distinct concern: tactic proof state, term type inspection, symbol lookup, module dependency analysis, and C FFI inspection. There is no overlap or ambiguity between these operations, even the two goal-related tools are clearly differentiated by context.

Naming Consistency5/5

All tool names follow a uniform pattern with the 'lean_' prefix and snake_case, using noun-based or verb-noun combinations consistently (e.g., lean_goal, lean_lookup_symbol). The naming is predictable and easy to infer purpose from.

Tool Count5/5

With 5 tools, the server is well-scoped for a Lean LSP integration, providing a focused set of capabilities without redundancy or bloat. Each tool serves a clear purpose in the interactive theorem proving workflow.

Completeness4/5

The tool set covers essential Lean-specific operations like goal queries and symbol lookup, but lacks common LSP features such as hover, diagnostics, or references. However, for a specialized Lean server, the core proving workflows are well-represented, with only minor gaps.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Enables LLM agents to interact with the Lean theorem prover through the Language Server Protocol, providing tools for analyzing Lean projects, accessing diagnostics, goal states, documentation, and searching for theorems using both local and external search services.
    23
    268,888 PyPI
    513
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides IDE-like code navigation and search for local repositories, enabling AI assistants to perform symbol search, trigram indexing, and semantic navigation.
    AGPL 3.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    Exposes type-aware code navigation and fast file search to AI agents via language servers, enabling definitions, references, symbols, and file lookup without reading entire codebases.
    1,077 npm
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables LLM agents to efficiently understand and navigate a codebase by providing semantic search over symbols and a reference graph, replacing expensive grep/glob calls with structured tools like definition lookup, caller/callee queries, and change-impact analysis.
    3
    MIT