A "code intepreter" for Lean
LeanTool is a simple utility that connects LLMs with a “Code Interpreter” for Lean. This is implemented as tool calls from the LLM to the Lean executable, hence the name.
Current LLMs often have trouble with outputing code with correct Lean 4 syntax, due to the recent rapid changes in the Lean language and its libraries. By allowing LLMs to talk directly to Lean, they are given opportunities to fix their mistakes. Furthermore, Lean being an interactive theorem prover, there are many interactive features that are not well represented in training data. This utility includes some initial efforts on prompting the LLMs with instructions on using these interactive features to better produce proofs.
Our design goal is to be flexible: easy to plug into automated workflows, but can also be plugged into human-facing chat/copilot interfaces.
This is part of a broader effort to create safe and hallucination-free coding AIs.
sorrys. This facilitates breaking complex proof tasks down into simpler subtasks, e.g. draft-sketch-prove.run_tests. See blog posts for details.A demo of the OpenAI-compatible API server is up at http://www.codeproofarena.com:8800/v1. To use it, connect your app to the above URL as the API Base URL, “provider” as OpenAI or OpenAI-compatible, “model” as one of the key names in the models dict in leantool.py, and API key as your API key for the chosen model. See below for specific set up details for OpenWebUI, Continue.dev, Cline and Aider.
curl https://raw.githubusercontent.com/leanprover/elan/master/elan-init.sh -sSf | sh
poetrygit clone --recurse-submodules https://github.com/stanford-centaur/PyPantograph.git
cd PyPantograph
For the current version of Pantograph (0.3.1), you’ll need to add one line to the file pyproject.toml at the end of
[tool.poetry]
include = [
{ path = "pantograph/pantograph-repl", format = ["sdist", "wheel"] },
{ path = "pantograph/lean-toolchain", format = ["sdist", "wheel"] },
]
to become
[tool.poetry]
include = [
{ path = "pantograph/pantograph-repl", format = ["sdist", "wheel"] },
{ path = "pantograph/lean-toolchain", format = ["sdist", "wheel"] },
{ path = "src", format = ["sdist", "wheel"] },
]
And then run
uv sync
uv build
For version 0.3.0 and earlier, do
poetry build
pyproject.toml in the LeanTool directory, to ensure the pantograph entry points to the correct path and file name to the .whl file.poetry installLiteLLM. E.g. for OpenAI, just set the environmental variable OPENAI_API_KEY.
For Anthropic, ANTHROPIC_API_KEY. If you want to try many different models, sign up for an OpenRouter
API key and set OPENROUTER_API_KEY. For local models served by ollama, start by installing ollama.
See Relevant LiteLLM Docs for more detailed instructions.
The models dict in leantool.py has some preset models; it has the format “short name” : “LiteLLM model name”. Modify it to have an entry for your model
if you have something different.leantool.py is the Python library. Simply import the file and call interactive_lean_check to invoke the feedback loop.
Currently used by FormalizeWithTest autoformalization project,
and WakingUp experiments on hallucination detection.interactive_lean_check call. Here is a tentative interface design. A plugin is a python object that has the following members:
sys_msg: a string that will be attached to the system messageasync def process(self, code, result): a method that will be executed after the main Lean executable finishes. Takes in the LLM submitted code, and result a dict that records the results of the processing so far. The method should return the new result dict.cli_chat.py command line chat interface. Simply run poetry run python cli_chat.py.app.py Streamlit chat interface.lean-api-server-flask.py OpenAI API compatible proxy server. Can be plugged into any application that takes a OpenAI API model with custom base URL.
Can either use the API keys set in the environment variables, or take an API key token in the request,
which is then passed to the corresponding LLM.
Has been tested to work with OpenWebUI, a fully featured chat interface,
and coding assistants Continue, Cline, and Aider.http://localhost:8000/v1:poetry run python lean-api-server-flask.py
--add-host host.docker.internal:host-gateway -e OPENAI_API_BASE_URL=http://host.docker.internal:8000/v1apiBase url.
Set the model name to be the key name of your chosen model in the models dict in leantool.py, e.g. “sonnet”.
For the apiKey field you may provide your API key for the chosen model.export OPENAI_API_BASE=<endpoint for the API server>
export OPENAI_API_KEY=<key for your chosen model>
## Prefix the model name with openai/
aider --model openai/sonnet
leanmcp.py is a Model Context Protocol (MCP) server. This exports Lean (and plugins including load_sorry) as a MCP tool, without the LLM and the feedback loop. Works with apps that can utilize MCP servers, and are able to manage the feedback loop within the app.
Has been tested to work with Claude Code, Cursor and Goose.stdio mode: e.g. when configuring your app for MCP, fill in the command poetry run python leanmcp.pysse mode: e.g. run poetry run python leanmcp.py --sse --port 8008,
then fill in the URL http://<your-host-or-ip-address>:8008/sse in your app’s configuration.claude mcp add LeanTool poetry run python leanmcp.py
poetry shell
claude
sse mode, run the server with poetry run python leanmcp.py --sse --port 8008,
then in Cursor, go to Cursor Settings > Features > MCP, click on the + Add New MCP Server button, and fill in the URL http://<your-host-or-ip-address>:8008/sse.sorry in place of the proof. Pass the code to the provided tool to check for syntax, and show me its output”. Cursor will show the MCP tool call; you may need to click the Run tool button to approve the call.Mcp Clickup
Mcp Duckduckgo
A DuckDuckGo search plugin for Model Context Protocol (MCP), compatible with Claude Code. Provides web search functionality with advanced navigation and content exploration features.
Perplexity Mcp Server
This Model Context Protocol (MCP) server enables LLMs like Claude to perform internet research using the Perplexity API. It provides real-time, up-to-date information with source citations.