Skip to content

Commit a98ca61

Browse files
ctothclaude
andcommitted
fix: add main() function to resolve script import error
- Add main() function to mcp_server_code_extractor.py for proper entry point - Bump version to 0.1.1 (bugfix release) - Rename file from mcp_code_extractor.py to mcp_server_code_extractor.py - Resolves ImportError: cannot import name 'main' when running uv tool run 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 3e7d662 commit a98ca61

File tree

2 files changed

+22
-38
lines changed

2 files changed

+22
-38
lines changed
Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,16 @@
1717
1818
**STOP USING READ/SEARCH/GREP FOR CODE INVESTIGATION!**
1919
20-
❌ **WRONG WORKFLOW** (what you used to do):
21-
Read(file) → Search(pattern) → Read(file) → Search(another pattern) → Edit
20+
❌ **WRONG**: Read(file) → Search(pattern) → Edit
21+
✅ **CORRECT**: get_symbols(file) → get_function(file, name) → Edit
2222
23-
✅ **CORRECT WORKFLOW** (what you should do):
24-
get_symbols(file) → get_function(file, name) → Edit
25-
get_symbols(file) → get_lines(file, start, end) → Edit
26-
get_symbols(file) → get_class(file, name) → Edit
27-
28-
**MANDATORY INVESTIGATION STEPS**:
23+
**MANDATORY STEPS**:
2924
1. ALWAYS start with get_symbols(file) to see what's in the file
3025
2. Use get_function(file, name) to extract specific functions
31-
3. Use get_lines(file, start, end) for targeted line ranges
32-
4. Use get_class(file, name) for class definitions
33-
5. NEVER use Read() to "examine" or "investigate" code files
34-
6. NEVER use Search() with function/class name patterns
35-
7. NEVER use Bash() with grep/tail/head commands
36-
37-
**🚫 USING Read() ON CODE FILES IS PROHIBITED:**
38-
- You will waste context reading entire files
39-
- You will miss function boundaries and structure
40-
- You will need to manually parse what tree-sitter does automatically
41-
- You will make mistakes finding the right code sections
42-
- These tools are specifically designed to replace Read() for code
26+
3. Use get_class(file, name) for class definitions
27+
4. NEVER use Read() to "examine" or "investigate" code files
28+
29+
**🚫 Using Read() on code files wastes context and misses structure**
4330
4431
**COMMON SCENARIOS**:
4532
- Testing: get_symbols(test_file) → get_function(test_file, "test_method_name")
@@ -141,7 +128,6 @@ def get_function(file_path: str, function_name: str) -> dict:
141128
142129
🎯 **PRECISE EXTRACTION** - Gets exact function boundaries with line numbers using tree-sitter.
143130
⚠️ **REPLACES Read() + manual parsing** - No need to read entire files and search manually.
144-
🚫 **NEVER use Read() then search for functions** - This tool does it correctly in one step.
145131
146132
Args:
147133
file_path: Path to the source file
@@ -150,8 +136,7 @@ def get_function(file_path: str, function_name: str) -> dict:
150136
Returns:
151137
dict with code, start_line, end_line, lines, function, file, language
152138
153-
**MANDATORY WORKFLOW**: get_symbols() first → get_function() for specific extraction → Edit
154-
**FORBIDDEN**: Read() → Search/Grep for function names → Edit (WRONG!)
139+
**WORKFLOW**: get_symbols() first → get_function() for specific extraction → Edit
155140
"""
156141

157142
if not os.path.exists(file_path):
@@ -259,7 +244,6 @@ def get_class(file_path: str, class_name: str) -> dict:
259244
260245
🎯 **PRECISE EXTRACTION** - Gets exact class boundaries with all methods using tree-sitter.
261246
⚠️ **REPLACES Read() + manual parsing** - No need to read entire files and search manually.
262-
🚫 **NEVER use Read() then search for classes** - This tool does it correctly in one step.
263247
264248
Args:
265249
file_path: Path to the source file
@@ -268,8 +252,7 @@ def get_class(file_path: str, class_name: str) -> dict:
268252
Returns:
269253
dict with code, start_line, end_line, lines, class, file, language
270254
271-
**MANDATORY WORKFLOW**: get_symbols() first → get_class() for specific extraction → Edit
272-
**FORBIDDEN**: Read() → Search/Grep for class names → Edit (WRONG!)
255+
**WORKFLOW**: get_symbols() first → get_class() for specific extraction → Edit
273256
"""
274257

275258
if not os.path.exists(file_path):
@@ -364,22 +347,20 @@ def find_class(node):
364347
@mcp.tool()
365348
def get_symbols(file_path: str) -> list:
366349
"""
367-
🚨 **MANDATORY FIRST STEP** for ALL code investigation - NEVER use Read() on code files!
350+
🚨 **ALWAYS USE THIS FIRST** for code investigation - DO NOT use Read() on code files!
368351
369352
List all functions, classes, and other symbols in a file with their line numbers.
370-
This is the ONLY CORRECT way to explore code structure instead of reading entire files.
353+
This is the CORRECT way to explore code structure instead of reading entire files.
371354
372-
⚠️ **COMPLETELY REPLACES Read() for code files** - More efficient and structured than reading entire files.
373-
🚫 **USING Read() ON CODE FILES IS WRONG** - You will miss functions and waste context.
355+
⚠️ **REPLACES Read() for code files** - More efficient and structured than reading entire files.
374356
375357
Args:
376358
file_path: Path to the source file to analyze
377359
378360
Returns:
379361
List of symbols with name, type, start_line, end_line, lines, and preview
380362
381-
**MANDATORY WORKFLOW**: get_symbols() → get_function()/get_class() → Edit
382-
**FORBIDDEN WORKFLOW**: Read → Search → Edit (THIS IS WRONG!)
363+
**WORKFLOW**: get_symbols() → get_function()/get_class() → Edit (NOT Read → Search → Edit)
383364
"""
384365

385366
if not os.path.exists(file_path):
@@ -545,7 +526,6 @@ def get_lines(file_path: str, start_line: int, end_line: int) -> dict:
545526
dict with code, start_line, end_line, lines, file, total_lines
546527
547528
**WORKFLOW**: get_symbols() first → get_lines() for specific ranges → Edit
548-
More efficient than reading entire files when you need specific line ranges with validation.
549529
"""
550530

551531
if not os.path.exists(file_path):
@@ -594,7 +574,6 @@ def get_signature(file_path: str, function_name: str) -> dict:
594574
dict with signature, name, file, start_line, lines
595575
596576
**WORKFLOW**: get_symbols() first → get_signature() for interface info → Edit
597-
More efficient than get_function when you only need the function interface, not implementation.
598577
"""
599578

600579
result = get_function(file_path, function_name)
@@ -621,7 +600,8 @@ def get_signature(file_path: str, function_name: str) -> dict:
621600
}
622601

623602

624-
if __name__ == "__main__":
603+
def main():
604+
"""Main entry point for the MCP server."""
625605
import sys
626606

627607
# If run with --help, show usage
@@ -653,3 +633,7 @@ def get_signature(file_path: str, function_name: str) -> dict:
653633

654634
# Otherwise run as MCP server
655635
mcp.run()
636+
637+
638+
if __name__ == "__main__":
639+
main()

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "mcp-server-code-extractor"
3-
version = "0.1.0"
3+
version = "0.1.1"
44
description = "A Model Context Protocol (MCP) server that provides precise code extraction tools using tree-sitter parsing"
55
readme = "README.md"
66
requires-python = ">=3.11"
@@ -36,7 +36,7 @@ Issues = "https://github.com/ctoth/mcp_server_code_extractor/issues"
3636
Documentation = "https://github.com/ctoth/mcp-code-extractor#readme"
3737

3838
[project.scripts]
39-
mcp-code-extractor = "mcp_code_extractor:main"
39+
mcp-server-code-extractor = "mcp_server_code_extractor:main"
4040

4141
[project.optional-dependencies]
4242
dev = [
@@ -51,4 +51,4 @@ requires = ["setuptools>=45", "wheel"]
5151
build-backend = "setuptools.build_meta"
5252

5353
[tool.setuptools]
54-
py-modules = ["mcp_code_extractor"]
54+
py-modules = ["mcp_server_code_extractor"]

0 commit comments

Comments
 (0)