███╗ ███╗ █████╗ ████████╗██╗ ██╗ ██████╗ ██████╗ ██████╗ ███████╗
████╗ ████║██╔══██╗╚══██╔══╝██║ ██║██╔════╝██╔═══██╗██╔══██╗██╔════╝
██╔████╔██║███████║ ██║ ███████║██║ ██║ ██║██║ ██║█████╗
██║╚██╔╝██║██╔══██║ ██║ ██╔══██║██║ ██║ ██║██║ ██║██╔══╝
██║ ╚═╝ ██║██║ ██║ ██║ ██║ ██║╚██████╗╚██████╔╝██████╔╝███████╗
╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝
Project Page: math-ai-org/mathcode
English | 中文
MathCode is a terminal AI coding assistant with built-in Lean capabilities. The agent can inspect goals, check candidates, search declarations, and verify a finished proof interactively.
git clone https://github.com/math-ai-org/mathcode.git
cd mathcode
bash setup.sh --with-lean
codex auth login
mathcodeFor a smaller installation without Lean/Mathlib, use
bash setup.sh --without-lean. You can add it later with
bash setup.sh --install-lean; the first approved local Lean feature call also
offers to install it. Running bash setup.sh interactively asks which mode to
use and defaults to the full installation.
setup.sh prepares the release checkout for daily use. It downloads or repairs
the bundled runtime, prepares local configuration, and installs a user-local
mathcode launcher for future shells. On Linux it also requires bwrap
(package bubblewrap) and socat before bootstrapping the Lean workspace.
If your current shell has not reloaded its profile yet, use ./run as the
bundle-local fallback.
Runtime files:
- downloads the matching
mathcode-vX.Y.Z-<os>-<arch>.tar.gzasset when bundled runtime files are missing, stale, unverified, or invalid for the current platform - restores
./mathcode,./mathcode-webui, andvendor/ripgrep/from that archive when repair is needed - verifies the current-platform
SHA256SUMS.txtentry withshasumorsha256sum - validates downloaded runtime files before replacing an existing working install
- records release metadata for the CLI and WebUI helper so later
setup.shandsetup.sh --statusruns can detect stale or unverified binaries
Local configuration:
- creates
.envfrom.env.examplewhen needed - installs a managed user-local
mathcodelauncher in~/.local/bin/by default - creates
tools/andplugins/extension directories plus the bundledskills/reference-doc directory; project skills load from.mathcode/skills/<name>/SKILL.md - ships a bundled
rgbinary undervendor/ripgrep/for MathCode's internal search paths
Lean toolchain:
- can be installed with
--with-lean, deferred with--without-lean, and added later with--install-leanor on the first approved local Lean use - ships the versioned
lean-workspace/lake-manifest.jsonso setup and local runs use the dependency graph locked by the release - setup materializes an empty managed
VaultLibs/UserVaultLibs/skeleton when needed; source-host local vault mirrors, test fixtures, and scratch Lean files are not packaged - materializes that locked graph during setup without running
lake updateor rewriting the manifest - requires a local
MathCodeLeanreadiness build after the optional Mathlib cache fetch; cache skips and download failures fall back to that build, and a build failure aborts setup - uses a complete bundle-local
.local/elanLean/Lake pair by default - accepts
lean.exe/lake.exepairs from Git Bash/MSYS - repairs partial local elan tool-file installs before bootstrapping the Lean workspace
- uses system Lean/Lake only when
MATHCODE_SETUP_USE_SYSTEM_LEAN=1and both tools are available, preserving your existingELAN_HOME
Setup only overwrites launcher files it previously created. This avoids
clobbering an unrelated existing mathcode command.
If MATHCODE_INSTALL_BIN_DIR is set, setup resolves relative paths against the
bundle root before writing the launcher, recorded state, or managed PATH block.
It also refreshes the managed profile block even when the chosen directory is
already on the current shell's PATH, so future shells keep resolving
mathcode.
If the selected launcher directory cannot be used, setup skips only the launcher step and continues the rest of the installation.
When MATHCODE_SETUP_USE_SYSTEM_LEAN=1, setup captures system lean and
lake before changing into the bundle root and records their validated absolute
paths in .env. Runtime resolution validates and uses that exact pair even when
a later process has a different PATH. These managed system paths use strict
base64: UTF-8 encoding so Bun dotenv parsing and ./run shell sourcing both
preserve literal backslashes, quotes, and backticks. Without that opt-in, setup
removes any stale managed system-toolchain selection and --status reports the
default local .local/elan path instead of treating system Lean as installed.
Generated .env path values are shell-quoted, so bundle paths containing
characters such as $ or single quotes remain literal when ./run sources the
file; the managed system Lean/Lake values use the dual-parser encoding above.
bash setup.sh --install-lean # add or repair optional Lean/Mathlib support
bash setup.sh --status # check whether the binary/tooling look healthy
bash setup.sh --clean # remove install artifacts, keep proofs/vault data
bash setup.sh --help # show all setup flagssetup.sh --status checks that:
./mathcode --versionand checksum match this release tag's metadata./mathcode-webuimatches the recorded release metadata- the current platform's bundled
rgis executable and reports a ripgrep version banner - optional Lean support is ready, deferred, incomplete, or not yet installed
setup.sh --clean preserves user outputs in LeanFormalizations/, vault
data, and the release's locked Lake manifest. If setup previously recorded a managed launcher, later --status and
--clean runs keep tracking it even when MATHCODE_INSTALL_BIN_DIR is unset.
- macOS (arm64) or glibc-based Linux (x86_64 with AVX2, built on Ubuntu 22.04)
curlfor setup/bootstrap downloadsshasumorsha256sumfor release archive verification and metadata- enough disk space for the bundle, plus the Lean toolchain and Mathlib caches when Lean support is enabled
codexCLI if you want the default backend and default math flow- Python 3.12+ (optional, only needed for analysis tools in
tools/)
mathcode -p "prove that the square of an even number is even"
echo "hello" | mathcode -p
mathcode --helpMCP XAA IdP setup requires a nonblank HTTPS issuer URL.
mathcode mcp xaa setup --issuer ... rejects http://, including loopback
URLs, before writing settings.
If you have not reloaded your shell yet, use the bundle-local fallback:
./run -p "prove that the square of an even number is even"
echo "hello" | ./run -p
./run --helpThe agent edits Lean files in the selected workspace. The atomic Lean tools do not create a separate run directory or write proof-library artifacts.
./run webui./run webui sources the bundle .env, starts the local daemon, and prints the
browser authentication URL.
If launched directly, the packaged ./mathcode-webui helper re-enters the
sibling ./run webui wrapper first. Direct and wrapper launches therefore use
the same .env, local Lean toolchain, and bundle defaults. A present but
broken wrapper is reported as a launch failure.
Inside an interactive ./run session, /webui and /webUI launch or manage
the same local daemon. The slash command supports --no-browser,
--port <port>, --status, and --stop; source-only --rebuild is not
available in release bundles. The full authenticated URL is written only to the
local terminal, while command result/status text redacts it as
token=<redacted>. For slash-command launches, the selected port and workspace
override same-named WebUI keys from the bundle .env.
MATHCODE_GOAL_MAX_TOKEN_BUDGETcaps token budgets accepted by source/goal,/goaldaemon commands, and/api/v1/sessions/:id/goal. It accepts the same positive integer, integer-valued decimal, andk/m/bcompact formats as/goal; unset or invalid values fall back to1000000000.MATHCODE_MAX_CHAINED_COMMAND_INPUTScaps nested local slash-command next-input submissions beforeQueryEngineaborts. Unset or invalid values fall back to25.
Interactive release sessions support:
/goal <token-budget> <objective>/goal --budget <token-budget>/goal --budget=<token-budget>- optional
--max-continuations Nor--max-continuations=<N> /goal pause,/goal resume,/goal status, and/goal clear- bare
/goal,/goal help,/goal -h, and/goal --help
The command continues the same session; it does not spawn a separate agent.
Objectives that begin with / are submitted as plain goal text, not parsed as
another slash command.
After a budget, --help can be the first objective token. Once objective
parsing has started, flag-looking tokens remain objective text unless a valid
later --budget is being used to supply the required explicit budget.
Invalid --budget values are rejected when --budget is parsed as the budget
option, including numeric-expression objectives like:
1 + 1 ... --budget nope
Use --effort <level> or interactive /effort <level> with low, medium,
high, max, or a positive integer; /effort auto and /effort unset return
the session to the model default.
For CLI model overrides, the reserved default value is matched
case-insensitively; custom model IDs keep their original casing.
Custom agent definitions trim description, JSON prompt, markdown prompt
bodies, initialPrompt, and JSON enum fields such as effort,
permissionMode, memory, and isolation; blank required
descriptions/prompts are rejected, and blank optional initial prompts are
ignored. JSON skills lists are normalized like markdown frontmatter.
Interactive context displays keep diagnostic context intact:
/contextuses the same visible markdown transcript output in interactive and non-interactive sessions/configincludes a default-onShow tool-use warningstoggle. Disabling it suppresses only non-error runtime warning transcript events that are not stream parser/drop diagnostics; tool errors, permission denials, validation failures, stream-json parser diagnostics, and actionable tool-call diagnostics remain visible to the agent.- markdown table cells are escaped
- slash-command and deferred built-in tool details remain visible
- MCP loaded/available status is shown
- deferred categories are excluded from current-usage tables
- manual compact reserve is shown as reserved buffer
- free/reserved rows stay visible when current usage is empty
- malformed token rows and zero-token synthetic windows do not produce invalid suggestion percentages
- server-side and MCP tool blocks are counted in message breakdowns
Compact and autocompact paths:
- clamp malformed thresholds, token counts, legacy content shapes, and blank tool IDs
- preserve singleton tool-result pairs
- scope statusline, away summary, survey, and sticky-prompt UI to the active post-compact transcript
- suppress stale warnings after partial compact
- coalesce duplicate remote compacting statuses
Task handling:
/tasks,TaskStop, and SDKstop_taskdo not count the selectable leader row as a running teammate- pending remote agents and running in-process teammates can be stopped
- task tools and SDK
stop_tasktrim task IDs - deprecated
shell_idand TaskOutputagentId/bash_idaliases can backfill blanktask_idvalues - legacy
wait_up_toseconds are normalized - legacy persisted task statuses are recovered across user-visible status shapes
- legacy
TaskUpdatestatus aliases are accepted - blank task text fields are rejected
- task metadata keys are trimmed, and blank or unsafe
__proto__metadata keys are rejected - TaskOutput timeouts must be integer-valued
- idle in-process teammate output is treated as ready instead of waiting for timeout
- mixed text/structured TaskOutput and TaskStop results replay correctly
- legacy TaskOutput output replay preserves tag-looking text such as
<error> - trimming command whitespace does not create false TaskStop truncation markers
- recently completed rows expire on schedule, while hidden summaries remain visible in very short terminals
Shell sleep auto-backgrounding and path validation recognize:
- decimal, suffixed, signed, exponent, and trailing-dot durations, such as
sleep 2s,sleep 2m,sleep +2, andsleep 2e0 - wrapped shell forms such as
env ... sleep 2s - PowerShell quoted, commented, redirected, and module-qualified sleep commands,
such as
& 'sleep' 2,Start-Sleep -Seconds:2 > $null, andMicrosoft.PowerShell.Utility\Start-Sleep -Seconds 2 - TimeSpan
-Durationvalues, PowerShell parameter abbreviations and common parameters - short, fractional, signed, and exponent
timeoutwrappers
Eligible generic compile callers can opt into the in-process Lean REPL:
MATHCODE_LEAN_REPL=1An external Kimina Lean Server can additionally serve atomic exploration:
MATHCODE_KIMINA_SERVER=1
MATHCODE_KIMINA_CMD="/absolute/path/to/kimina-lean-server/.venv/bin/python -m server"
MATHCODE_KIMINA_CWD=/absolute/path/to/kimina-lean-server
MATHCODE_KIMINA_PROJECT_ROOT=/absolute/path/to/served-lean-projectOn macOS, LeanGoal and LeanCheck reuse that server only when the declared project
matches the resolved project and a live guard confirms its Lean version.
Otherwise they fall back to the pinned subprocess and expose the reason as a
warning. Kimina feedback is not a completion certificate. LeanVerify and
isolated paper agents always use fresh isolated subprocesses. MathCode launches
Kimina loopback-only inside its fail-closed Lean sandbox, with a random bearer
key that never enters the Lean REPL environment, no provider credentials, and
scratch-only writes. A virtualenv, when used, must live below
MATHCODE_KIMINA_CWD, and MATHCODE_KIMINA_CMD must start directly with that
Python executable rather than a command wrapper. Manifest roots that contain the project or another
protected host scope are rejected, and remote-package storage stays inside the
project. A standard-library-only Python guardian lives in a separate read-only
support root and reuses the selected Kimina interpreter, so no MathCode source
tree or second runtime is exposed to the sandbox. Python site, .pth, and
sitecustomize loading are disabled before the handoff path enters that
interpreter. It mediates supported
setsid Lake launches, deletes the mode-0600 auth handoff and strips both
Kimina key names plus its private environment before Lean starts, and kills its
separately owned Lake group through an independent owner-pipe HUP observer, even
when Lake stops reading input. Parent exit and
SIGINT/SIGTERM/SIGHUP
also clean the complete owned tree. Current /api/check caller cancellation
preserves the shared service; legacy /verify cancellation or uncertain
backend/transport state cleans up the complete service tree before restart.
Linux and Windows use pinned subprocesses.
/plan stores session plan markdown in the active user config-home plans/
slot by default (~/.mathcode/plans/ unless MATHCODE_CONFIG_DIR relocates
the config home). To keep plan files under the project tree, set
plansDirectory in project or local settings to a custom directory relative to
the project root. Nested directories are created as needed, and symlink escapes
fall back to the user config-home plans/ directory.
Manage an explicit library of proved theorems:
/theorem-store store <file> <qualified-declaration> # verify and store one theorem
/theorem-store sync # inspect candidates and ask which declarations to store
/theorem-store check # compile-check the assembled library
/theorem-store status # show stored count and vault info/theorem-store store calls LeanTheoremLibrary for one explicit fully
qualified declaration. The tool performs fresh strict verification, rechecks
the source and dependency snapshot immediately before persistence, then
strictly verifies the exact renamed declaration in the assembled Stored.lean.
The elaborated proposition must remain identical, and success immediately
builds an importable workspace module. The library, workspace mirror, compiled
artifacts, and index update as one rollback-capable transaction.
Private theorem compilation and public Lake publication each have a separate
bounded 300-second build budget; a timeout still rolls the transaction back
without exposing incomplete artifacts.
/theorem-store sync is optional
agent guidance: it discovers candidates, asks which declarations to store, then
uses the same one-declaration tool call for each confirmed candidate. Atomic
Lean feedback tools never append to the theorem library as a hidden effect.
Store conversational assumptions as persistent, consistency-checked declarations:
/axiomatize "A is faster than B" # formalize + store
/axiomatize list # show all active axioms
/axiomatize check # consistency review
/axiomatize remove <name> # remove a declarationAxioms are stored per vault with Lean formalization and compile checks. Atomic Lean tool calls do not inject them implicitly; import or reference the stored declarations explicitly when they are part of the intended proof context.
Generate an Obsidian vault that visualizes theorem dependencies as a knowledge graph:
/obsidian on # enable + generate from existing formalizations
/obsidian off # disable
/obsidian generate # regenerate nowUse /obsidian generate after changing proofs to refresh the vault explicitly.
Atomic Lean tool calls never update it as a hidden side effect. Open it in
Obsidian and use Graph View to see theorem-to-lemma relationships.
Refreshes overwrite MathCode-managed notes and exact legacy MathCode projections
from before the managed marker existed; those legacy notes gain the marker. If
a theorem, lemma, index, or blueprint filename is occupied by any other user
note, generation fails and preserves that note.
Each lemma stub includes the full Lean definition queried from Mathlib via
#print.
For ordinary Lean work, the agent can choose among four atomic tools:
LeanGoalinspects one explicit source position.LeanCheckcompiles a file or ephemeral candidate and returns structured feedback.LeanSearchqueries one explicit provider without hidden fan-out.LeanVerifyperforms the strict final check for one fully qualified declaration; onlydata.verified=truecertifies completion.
The optional /lean skill offers guidance without imposing a fixed phase,
tactic order, retry budget, or planner. The former fixed controllers have been
removed and are not release entrypoints or model-visible tools.
The fixed scheme is retired, not the useful methods: the agent may still choose
subgoal decomposition, helper lemmas, branching, milestones, stuck detection,
diagnostic repair, and theorem reuse, then reorder or abandon them freely.
Axiom and theorem libraries are separate explicit actions, never hidden effects
of an atomic Lean call.
Strict verification resolves Lean/Lake executables outside the project tree,
preserves Lake's canonical source/module context, and obtains target axiom
usage plus direct module axioms through Lean's environment API rather than
source-controlled macros or output.
The bundled CLI ships with recurring prompt scheduling enabled out of the box.
Inside interactive MathCode sessions you can use:
/loop 10m check the deploy
/loop 1h /standup 1Use short-lived loops for reminders and monitoring. When you want a schedule to survive restarts, create a durable schedule from the interactive session.
MathCode supports three extension mechanisms:
Add project-local skills at .mathcode/skills/<name>/SKILL.md. Each skill
uses its own directory; standalone skills/*.md files are not loaded.
Drop Python .py scripts with YAML frontmatter to add analysis tools. Auto-discovered at startup.
3 analysis tools are included: axiom-checker, lib-search, and
proof-stats. They remain available when MathCode is launched from another
workspace; a workspace-local tool with the same normalized name overrides the
bundled copy. Python 3.12+ is required only if you use these tools.
Drop plugin folders with .mathcode-plugin/plugin.json manifests to add commands, skills, agents, MCP servers, hooks, and more. Load via --plugin-dir or install from Git repos via /plugin.
No .env edits are required for the default path.
codex auth login
mathcodeIf you are still in the same shell where setup just finished, ./run is the immediate fallback until you reload your shell profile.
The packaged .env template now selects GPT-5.6 Sol at xhigh reasoning effort.
To apply the same values to an existing .env created by an older release and
also select the CLI's maximum effort level, set:
OPENAI_MODEL=gpt-5.6-sol
OPENAI_SMALL_MODEL=gpt-5.6-sol
OPENAI_REASONING_EFFORT=xhigh
MATHCODE_EFFORT_LEVEL=maxTo use an Anthropic-compatible backend instead, set:
MATHCODE_USE_OPENAI=0
ANTHROPIC_API_KEY=sk-ant-...
ANTHROPIC_MODEL=claude-sonnet-4-5The release ./run wrapper sources the bundle .env before launching
MathCode. For interactive /webui slash-command launches, the selected WebUI
port and workspace override same-named keys from that .env.
The WebUI route default is separate from the CLI .env: fresh WebUI settings
use openai / gpt-5.6-sol, while an existing saved provider/model selection
is preserved rather than rewritten.
In the WebUI settings panel, provider-key rows are limited to secrets the
daemon can pass to real child sessions today: anthropic and openrouter.
Codex/OpenAI routes use Codex OAuth, not an OPENAI_API_KEY row.
WebUI minimal reasoning effort is preserved for OpenAI/OpenRouter routes and
maps to the CLI's lowest available low effort on Anthropic-compatible routes.
The release binary bundles the provider SDKs used by the Anthropic-compatible,
Bedrock, Vertex, and Foundry branches, plus the MCPB/DXT plugin package; these
routes do not require a source checkout's node_modules. Bedrock, Vertex, and
Foundry use their provider-specific credentials rather than
Anthropic-compatible ANTHROPIC_AUTH_TOKEN / apiKeyHelper bearer headers.
Q: mathcode is not found right after setup
Open a new shell, or run:
source ~/.zshrcIf you want to keep working immediately before reloading your shell, use:
./runQ: ./run fails with exec format error, Bad CPU type in executable, or a similar startup error
You probably downloaded the wrong binary for your platform. Re-run bash setup.sh, or download the correct release asset manually from GitHub Releases.
Q: Startup says Codex auth is missing
Run:
codex auth loginQ: Can I skip cloning and just download a release asset
Yes. You can download and extract the .tar.gz bundle from GitHub Releases
directly.
The archive is self-contained; bash setup.sh only downloads from GitHub when
bundled runtime files are missing, stale, or unverified. The bootstrap repo just
makes bash setup.sh the default path.
Track the project's growth over time here:
If you use MathCode in research, please cite it as:
@misc{mathcode2026,
title = {MathCode: A Frontier Mathematical Coding Agent},
author = {Team Math-AI},
journal = {math-ai-org.github.io},
year = {2026},
month = {April},
url = "https://github.com/math-ai-org/mathcode"
}Join our Discord for help, feedback, and discussion: discord.gg/f2AFP9W5
MathCode preserves useful proof-search ideas as optional agent guidance while Lean remains the proof authority.
