lean-lsp-mcp 0.10.1__tar.gz → 0.10.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {lean_lsp_mcp-0.10.1/src/lean_lsp_mcp.egg-info → lean_lsp_mcp-0.10.3}/PKG-INFO +4 -4
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/README.md +1 -1
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/pyproject.toml +3 -3
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/src/lean_lsp_mcp/server.py +51 -4
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3/src/lean_lsp_mcp.egg-info}/PKG-INFO +4 -4
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/src/lean_lsp_mcp.egg-info/requires.txt +2 -2
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/tests/test_project_tools.py +12 -28
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/LICENSE +0 -0
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/setup.cfg +0 -0
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/src/lean_lsp_mcp/__init__.py +0 -0
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/src/lean_lsp_mcp/__main__.py +0 -0
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/src/lean_lsp_mcp/client_utils.py +0 -0
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/src/lean_lsp_mcp/file_utils.py +0 -0
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/src/lean_lsp_mcp/instructions.py +0 -0
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/src/lean_lsp_mcp/search_utils.py +0 -0
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/src/lean_lsp_mcp/utils.py +0 -0
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/src/lean_lsp_mcp.egg-info/SOURCES.txt +0 -0
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/src/lean_lsp_mcp.egg-info/dependency_links.txt +0 -0
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/src/lean_lsp_mcp.egg-info/entry_points.txt +0 -0
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/src/lean_lsp_mcp.egg-info/top_level.txt +0 -0
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/tests/test_editor_tools.py +0 -0
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/tests/test_logging.py +0 -0
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/tests/test_misc_tools.py +0 -0
- {lean_lsp_mcp-0.10.1 → lean_lsp_mcp-0.10.3}/tests/test_search_tools.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lean-lsp-mcp
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.3
|
|
4
4
|
Summary: Lean Theorem Prover MCP
|
|
5
5
|
Author-email: Oliver Dressler <hey@oli.show>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -8,8 +8,8 @@ Project-URL: Repository, https://github.com/oOo0oOo/lean-lsp-mcp
|
|
|
8
8
|
Requires-Python: >=3.10
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
License-File: LICENSE
|
|
11
|
-
Requires-Dist: leanclient==0.3.
|
|
12
|
-
Requires-Dist: mcp[cli]==1.
|
|
11
|
+
Requires-Dist: leanclient==0.3.1
|
|
12
|
+
Requires-Dist: mcp[cli]==1.19.0
|
|
13
13
|
Requires-Dist: orjson>=3.11.1
|
|
14
14
|
Provides-Extra: lint
|
|
15
15
|
Requires-Dist: ruff>=0.2.0; extra == "lint"
|
|
@@ -134,7 +134,7 @@ You can find more details about MCP server configuration for Claude Code [here](
|
|
|
134
134
|
|
|
135
135
|
#### Claude Skill: Lean4 Theorem Proving
|
|
136
136
|
|
|
137
|
-
If you are using [Claude Desktop](https://modelcontextprotocol.io/quickstart/user) or [Claude Code](https://claude.ai/code), you can also install the [Lean4 Theorem Proving Skill](https://github.com/cameronfreer/lean4-skills/tree/main/lean4-theorem-proving). This skill provides additional prompts and templates for interacting with Lean4 projects and includes a section on interacting with the `lean-lsp-mcp` server.
|
|
137
|
+
If you are using [Claude Desktop](https://modelcontextprotocol.io/quickstart/user) or [Claude Code](https://claude.ai/code), you can also install the [Lean4 Theorem Proving Skill](https://github.com/cameronfreer/lean4-skills/tree/main/plugins/lean4-theorem-proving). This skill provides additional prompts and templates for interacting with Lean4 projects and includes a section on interacting with the `lean-lsp-mcp` server.
|
|
138
138
|
|
|
139
139
|
### 4. Install ripgrep (optional but recommended)
|
|
140
140
|
|
|
@@ -112,7 +112,7 @@ You can find more details about MCP server configuration for Claude Code [here](
|
|
|
112
112
|
|
|
113
113
|
#### Claude Skill: Lean4 Theorem Proving
|
|
114
114
|
|
|
115
|
-
If you are using [Claude Desktop](https://modelcontextprotocol.io/quickstart/user) or [Claude Code](https://claude.ai/code), you can also install the [Lean4 Theorem Proving Skill](https://github.com/cameronfreer/lean4-skills/tree/main/lean4-theorem-proving). This skill provides additional prompts and templates for interacting with Lean4 projects and includes a section on interacting with the `lean-lsp-mcp` server.
|
|
115
|
+
If you are using [Claude Desktop](https://modelcontextprotocol.io/quickstart/user) or [Claude Code](https://claude.ai/code), you can also install the [Lean4 Theorem Proving Skill](https://github.com/cameronfreer/lean4-skills/tree/main/plugins/lean4-theorem-proving). This skill provides additional prompts and templates for interacting with Lean4 projects and includes a section on interacting with the `lean-lsp-mcp` server.
|
|
116
116
|
|
|
117
117
|
### 4. Install ripgrep (optional but recommended)
|
|
118
118
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "lean-lsp-mcp"
|
|
3
|
-
version = "0.10.
|
|
3
|
+
version = "0.10.3"
|
|
4
4
|
description = "Lean Theorem Prover MCP"
|
|
5
5
|
authors = [{name="Oliver Dressler", email="hey@oli.show"}]
|
|
6
6
|
readme = "README.md"
|
|
7
7
|
requires-python = ">=3.10"
|
|
8
8
|
license = "MIT"
|
|
9
9
|
dependencies = [
|
|
10
|
-
"leanclient==0.3.
|
|
11
|
-
"mcp[cli]==1.
|
|
10
|
+
"leanclient==0.3.1",
|
|
11
|
+
"mcp[cli]==1.19.0",
|
|
12
12
|
"orjson>=3.11.1",
|
|
13
13
|
]
|
|
14
14
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import asyncio
|
|
1
2
|
import os
|
|
2
3
|
import re
|
|
3
4
|
import time
|
|
@@ -123,7 +124,7 @@ def rate_limited(category: str, max_requests: int, per_seconds: int):
|
|
|
123
124
|
|
|
124
125
|
# Project level tools
|
|
125
126
|
@mcp.tool("lean_build")
|
|
126
|
-
def lsp_build(ctx: Context, lean_project_path: str = None, clean: bool = False) -> str:
|
|
127
|
+
async def lsp_build(ctx: Context, lean_project_path: str = None, clean: bool = False) -> str:
|
|
127
128
|
"""Build the Lean project and restart the LSP Server.
|
|
128
129
|
|
|
129
130
|
Use only if needed (e.g. new imports).
|
|
@@ -152,13 +153,59 @@ def lsp_build(ctx: Context, lean_project_path: str = None, clean: bool = False)
|
|
|
152
153
|
subprocess.run(["lake", "clean"], cwd=lean_project_path_obj, check=False)
|
|
153
154
|
logger.info("Ran `lake clean`")
|
|
154
155
|
|
|
155
|
-
|
|
156
|
-
|
|
156
|
+
# Fetch cache
|
|
157
|
+
subprocess.run(["lake", "exe", "cache", "get"], cwd=lean_project_path_obj, check=False)
|
|
158
|
+
|
|
159
|
+
# Run build with progress reporting
|
|
160
|
+
process = await asyncio.create_subprocess_exec(
|
|
161
|
+
"lake", "build", "--verbose",
|
|
162
|
+
cwd=lean_project_path_obj,
|
|
163
|
+
stdout=asyncio.subprocess.PIPE,
|
|
164
|
+
stderr=asyncio.subprocess.STDOUT
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
output_lines = []
|
|
168
|
+
|
|
169
|
+
while True:
|
|
170
|
+
line = await process.stdout.readline()
|
|
171
|
+
if not line:
|
|
172
|
+
break
|
|
173
|
+
|
|
174
|
+
line_str = line.decode('utf-8', errors='replace').rstrip()
|
|
175
|
+
output_lines.append(line_str)
|
|
176
|
+
|
|
177
|
+
# Parse progress: look for pattern like "[2/8]" or "[10/100]"
|
|
178
|
+
match = re.search(r'\[(\d+)/(\d+)\]', line_str)
|
|
179
|
+
if match:
|
|
180
|
+
current_job = int(match.group(1))
|
|
181
|
+
total_jobs = int(match.group(2))
|
|
182
|
+
|
|
183
|
+
# Extract what's being built
|
|
184
|
+
# Line format: "ℹ [2/8] Built TestLeanBuild.Basic (1.6s)"
|
|
185
|
+
desc_match = re.search(r'\[\d+/\d+\]\s+(.+?)(?:\s+\(\d+\.?\d*[ms]+\))?$', line_str)
|
|
186
|
+
description = desc_match.group(1) if desc_match else "Building"
|
|
187
|
+
|
|
188
|
+
# Report progress using dynamic totals from Lake
|
|
189
|
+
await ctx.report_progress(
|
|
190
|
+
progress=current_job,
|
|
191
|
+
total=total_jobs,
|
|
192
|
+
message=description
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
await process.wait()
|
|
196
|
+
|
|
197
|
+
if process.returncode != 0:
|
|
198
|
+
build_output = "\n".join(output_lines)
|
|
199
|
+
raise Exception(f"Build failed with return code {process.returncode}")
|
|
200
|
+
|
|
201
|
+
# Start LSP client (without initial build since we just did it)
|
|
202
|
+
with OutputCapture():
|
|
203
|
+
client = LeanLSPClient(lean_project_path_obj, initial_build=False, prevent_cache_get=True)
|
|
157
204
|
|
|
158
205
|
logger.info("Built project and re-started LSP client")
|
|
159
206
|
|
|
160
207
|
ctx.request_context.lifespan_context.client = client
|
|
161
|
-
build_output =
|
|
208
|
+
build_output = "\n".join(output_lines)
|
|
162
209
|
return build_output
|
|
163
210
|
except Exception as e:
|
|
164
211
|
return f"Error during build:\n{str(e)}\n{build_output}"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lean-lsp-mcp
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.3
|
|
4
4
|
Summary: Lean Theorem Prover MCP
|
|
5
5
|
Author-email: Oliver Dressler <hey@oli.show>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -8,8 +8,8 @@ Project-URL: Repository, https://github.com/oOo0oOo/lean-lsp-mcp
|
|
|
8
8
|
Requires-Python: >=3.10
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
License-File: LICENSE
|
|
11
|
-
Requires-Dist: leanclient==0.3.
|
|
12
|
-
Requires-Dist: mcp[cli]==1.
|
|
11
|
+
Requires-Dist: leanclient==0.3.1
|
|
12
|
+
Requires-Dist: mcp[cli]==1.19.0
|
|
13
13
|
Requires-Dist: orjson>=3.11.1
|
|
14
14
|
Provides-Extra: lint
|
|
15
15
|
Requires-Dist: ruff>=0.2.0; extra == "lint"
|
|
@@ -134,7 +134,7 @@ You can find more details about MCP server configuration for Claude Code [here](
|
|
|
134
134
|
|
|
135
135
|
#### Claude Skill: Lean4 Theorem Proving
|
|
136
136
|
|
|
137
|
-
If you are using [Claude Desktop](https://modelcontextprotocol.io/quickstart/user) or [Claude Code](https://claude.ai/code), you can also install the [Lean4 Theorem Proving Skill](https://github.com/cameronfreer/lean4-skills/tree/main/lean4-theorem-proving). This skill provides additional prompts and templates for interacting with Lean4 projects and includes a section on interacting with the `lean-lsp-mcp` server.
|
|
137
|
+
If you are using [Claude Desktop](https://modelcontextprotocol.io/quickstart/user) or [Claude Code](https://claude.ai/code), you can also install the [Lean4 Theorem Proving Skill](https://github.com/cameronfreer/lean4-skills/tree/main/plugins/lean4-theorem-proving). This skill provides additional prompts and templates for interacting with Lean4 projects and includes a section on interacting with the `lean-lsp-mcp` server.
|
|
138
138
|
|
|
139
139
|
### 4. Install ripgrep (optional but recommended)
|
|
140
140
|
|
|
@@ -28,33 +28,16 @@ def _mathlib_file(test_project_path: Path) -> Path:
|
|
|
28
28
|
return candidate
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
def _first_occurrence_location(source: str, needle: str) -> tuple[int, int]:
|
|
32
|
-
for line_number, line in enumerate(source.splitlines(), start=1):
|
|
33
|
-
if needle not in line:
|
|
34
|
-
continue
|
|
35
|
-
stripped = line.lstrip()
|
|
36
|
-
if (
|
|
37
|
-
stripped.startswith("--")
|
|
38
|
-
or stripped.startswith("/-")
|
|
39
|
-
or stripped.startswith("*")
|
|
40
|
-
):
|
|
41
|
-
continue
|
|
42
|
-
column = line.index(needle) + 1
|
|
43
|
-
return line_number, column
|
|
44
|
-
|
|
45
|
-
pytest.skip(
|
|
46
|
-
f"Cannot find `{needle}` in executable mathlib code; update the test to match new contents."
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
|
|
50
31
|
@pytest.mark.asyncio
|
|
51
32
|
async def test_mathlib_file_roundtrip(
|
|
52
33
|
mcp_client_factory: Callable[[], AsyncContextManager[MCPClient]],
|
|
53
34
|
test_project_path: Path,
|
|
54
35
|
) -> None:
|
|
36
|
+
"""Test reading mathlib files and querying hover/term info."""
|
|
55
37
|
target_file = _mathlib_file(test_project_path)
|
|
56
38
|
|
|
57
39
|
async with mcp_client_factory() as mcp_client:
|
|
40
|
+
# Test reading file contents
|
|
58
41
|
contents = await mcp_client.call_tool(
|
|
59
42
|
"lean_file_contents",
|
|
60
43
|
{
|
|
@@ -64,28 +47,29 @@ async def test_mathlib_file_roundtrip(
|
|
|
64
47
|
)
|
|
65
48
|
text = result_text(contents)
|
|
66
49
|
assert "import Mathlib" in text
|
|
50
|
+
assert "Nat" in text
|
|
67
51
|
|
|
68
|
-
|
|
69
|
-
|
|
52
|
+
# Test hover on a stable position (line 33: "le := Nat.le" in instance declaration)
|
|
70
53
|
hover = await mcp_client.call_tool(
|
|
71
54
|
"lean_hover_info",
|
|
72
55
|
{
|
|
73
56
|
"file_path": str(target_file),
|
|
74
|
-
"line":
|
|
75
|
-
"column":
|
|
57
|
+
"line": 33,
|
|
58
|
+
"column": 11, # Position on 'Nat.le'
|
|
76
59
|
},
|
|
77
60
|
)
|
|
78
61
|
hover_text = result_text(hover)
|
|
79
|
-
assert "Nat.
|
|
62
|
+
assert "Nat.le" in hover_text or "LE" in hover_text or "le" in hover_text
|
|
80
63
|
|
|
64
|
+
# Test term goal (may or may not be valid at this position)
|
|
81
65
|
term_goal = await mcp_client.call_tool(
|
|
82
66
|
"lean_term_goal",
|
|
83
67
|
{
|
|
84
68
|
"file_path": str(target_file),
|
|
85
|
-
"line":
|
|
86
|
-
"column":
|
|
69
|
+
"line": 33,
|
|
70
|
+
"column": 11,
|
|
87
71
|
},
|
|
88
72
|
)
|
|
89
73
|
type_text = result_text(term_goal)
|
|
90
|
-
|
|
91
|
-
assert
|
|
74
|
+
# Accept either a valid type or the "not valid" message
|
|
75
|
+
assert len(type_text) > 0
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|