tree-sitter-analyzer 0.9.1__py3-none-any.whl → 0.9.3__py3-none-any.whl

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.

Potentially problematic release.


This version of tree-sitter-analyzer might be problematic. Click here for more details.

Files changed (64) hide show
  1. tree_sitter_analyzer/__init__.py +132 -132
  2. tree_sitter_analyzer/__main__.py +11 -11
  3. tree_sitter_analyzer/api.py +533 -533
  4. tree_sitter_analyzer/cli/__init__.py +39 -39
  5. tree_sitter_analyzer/cli/__main__.py +12 -12
  6. tree_sitter_analyzer/cli/commands/__init__.py +26 -26
  7. tree_sitter_analyzer/cli/commands/advanced_command.py +88 -88
  8. tree_sitter_analyzer/cli/commands/base_command.py +181 -178
  9. tree_sitter_analyzer/cli/commands/structure_command.py +138 -138
  10. tree_sitter_analyzer/cli/commands/summary_command.py +101 -101
  11. tree_sitter_analyzer/cli_main.py +7 -3
  12. tree_sitter_analyzer/core/__init__.py +15 -15
  13. tree_sitter_analyzer/core/analysis_engine.py +91 -87
  14. tree_sitter_analyzer/core/cache_service.py +320 -320
  15. tree_sitter_analyzer/core/engine.py +566 -566
  16. tree_sitter_analyzer/core/parser.py +293 -293
  17. tree_sitter_analyzer/encoding_utils.py +459 -459
  18. tree_sitter_analyzer/file_handler.py +210 -210
  19. tree_sitter_analyzer/formatters/__init__.py +1 -1
  20. tree_sitter_analyzer/formatters/base_formatter.py +167 -167
  21. tree_sitter_analyzer/formatters/formatter_factory.py +78 -78
  22. tree_sitter_analyzer/formatters/java_formatter.py +18 -18
  23. tree_sitter_analyzer/formatters/python_formatter.py +19 -19
  24. tree_sitter_analyzer/interfaces/__init__.py +9 -9
  25. tree_sitter_analyzer/interfaces/cli.py +528 -528
  26. tree_sitter_analyzer/interfaces/cli_adapter.py +344 -343
  27. tree_sitter_analyzer/interfaces/mcp_adapter.py +206 -206
  28. tree_sitter_analyzer/language_detector.py +53 -53
  29. tree_sitter_analyzer/languages/__init__.py +10 -10
  30. tree_sitter_analyzer/languages/java_plugin.py +1 -1
  31. tree_sitter_analyzer/languages/javascript_plugin.py +446 -446
  32. tree_sitter_analyzer/languages/python_plugin.py +755 -755
  33. tree_sitter_analyzer/mcp/__init__.py +34 -45
  34. tree_sitter_analyzer/mcp/resources/__init__.py +44 -44
  35. tree_sitter_analyzer/mcp/resources/code_file_resource.py +209 -209
  36. tree_sitter_analyzer/mcp/server.py +623 -568
  37. tree_sitter_analyzer/mcp/tools/__init__.py +30 -30
  38. tree_sitter_analyzer/mcp/tools/analyze_scale_tool.py +681 -673
  39. tree_sitter_analyzer/mcp/tools/analyze_scale_tool_cli_compatible.py +247 -247
  40. tree_sitter_analyzer/mcp/tools/base_tool.py +54 -54
  41. tree_sitter_analyzer/mcp/tools/read_partial_tool.py +310 -308
  42. tree_sitter_analyzer/mcp/tools/table_format_tool.py +386 -379
  43. tree_sitter_analyzer/mcp/tools/universal_analyze_tool.py +563 -559
  44. tree_sitter_analyzer/mcp/utils/__init__.py +107 -107
  45. tree_sitter_analyzer/models.py +10 -10
  46. tree_sitter_analyzer/output_manager.py +253 -253
  47. tree_sitter_analyzer/plugins/__init__.py +280 -280
  48. tree_sitter_analyzer/plugins/base.py +529 -529
  49. tree_sitter_analyzer/plugins/manager.py +379 -379
  50. tree_sitter_analyzer/project_detector.py +330 -317
  51. tree_sitter_analyzer/queries/__init__.py +26 -26
  52. tree_sitter_analyzer/queries/java.py +391 -391
  53. tree_sitter_analyzer/queries/javascript.py +148 -148
  54. tree_sitter_analyzer/queries/python.py +285 -285
  55. tree_sitter_analyzer/queries/typescript.py +229 -229
  56. tree_sitter_analyzer/query_loader.py +257 -257
  57. tree_sitter_analyzer/security/boundary_manager.py +57 -51
  58. tree_sitter_analyzer/security/validator.py +246 -241
  59. tree_sitter_analyzer/utils.py +294 -277
  60. {tree_sitter_analyzer-0.9.1.dist-info → tree_sitter_analyzer-0.9.3.dist-info}/METADATA +13 -13
  61. tree_sitter_analyzer-0.9.3.dist-info/RECORD +77 -0
  62. {tree_sitter_analyzer-0.9.1.dist-info → tree_sitter_analyzer-0.9.3.dist-info}/entry_points.txt +1 -0
  63. tree_sitter_analyzer-0.9.1.dist-info/RECORD +0 -77
  64. {tree_sitter_analyzer-0.9.1.dist-info → tree_sitter_analyzer-0.9.3.dist-info}/WHEEL +0 -0
@@ -1,308 +1,310 @@
1
- #!/usr/bin/env python3
2
- """
3
- Read Code Partial MCP Tool
4
-
5
- This tool provides partial file reading functionality through the MCP protocol,
6
- allowing selective content extraction with line and column range support.
7
- """
8
-
9
- import json
10
- from pathlib import Path
11
- from typing import Any
12
-
13
- from ...file_handler import read_file_partial
14
- from ...security import SecurityValidator
15
- from ...utils import setup_logger
16
-
17
- # Set up logging
18
- logger = setup_logger(__name__)
19
-
20
-
21
- class ReadPartialTool:
22
- """
23
- MCP Tool for reading partial content from code files.
24
-
25
- This tool integrates with existing file_handler functionality to provide
26
- selective file content reading through the MCP protocol.
27
- """
28
-
29
- def __init__(self, project_root: str = None) -> None:
30
- """Initialize the read partial tool."""
31
- self.security_validator = SecurityValidator(project_root)
32
- logger.info("ReadPartialTool initialized with security validation")
33
-
34
- def get_tool_schema(self) -> dict[str, Any]:
35
- """
36
- Get the MCP tool schema for read_code_partial.
37
-
38
- Returns:
39
- Dictionary containing the tool schema
40
- """
41
- return {
42
- "type": "object",
43
- "properties": {
44
- "file_path": {
45
- "type": "string",
46
- "description": "Path to the code file to read",
47
- },
48
- "start_line": {
49
- "type": "integer",
50
- "description": "Starting line number (1-based)",
51
- "minimum": 1,
52
- },
53
- "end_line": {
54
- "type": "integer",
55
- "description": "Ending line number (1-based, optional - reads to end if not specified)",
56
- "minimum": 1,
57
- },
58
- "start_column": {
59
- "type": "integer",
60
- "description": "Starting column number (0-based, optional)",
61
- "minimum": 0,
62
- },
63
- "end_column": {
64
- "type": "integer",
65
- "description": "Ending column number (0-based, optional)",
66
- "minimum": 0,
67
- },
68
- "format": {
69
- "type": "string",
70
- "description": "Output format for the content",
71
- "enum": ["text", "json"],
72
- "default": "text",
73
- },
74
- },
75
- "required": ["file_path", "start_line"],
76
- "additionalProperties": False,
77
- }
78
-
79
- async def execute(self, arguments: dict[str, Any]) -> dict[str, Any]:
80
- """
81
- Execute the read_code_partial tool.
82
-
83
- Args:
84
- arguments: Tool arguments containing file_path, line/column ranges, and format
85
-
86
- Returns:
87
- Dictionary containing the partial file content and metadata (CLI --partial-read compatible format)
88
-
89
- Raises:
90
- ValueError: If required arguments are missing or invalid
91
- FileNotFoundError: If the specified file doesn't exist
92
- """
93
- # Validate required arguments
94
- if "file_path" not in arguments:
95
- raise ValueError("file_path is required")
96
-
97
- if "start_line" not in arguments:
98
- raise ValueError("start_line is required")
99
-
100
- file_path = arguments["file_path"]
101
- start_line = arguments["start_line"]
102
- end_line = arguments.get("end_line")
103
- start_column = arguments.get("start_column")
104
- end_column = arguments.get("end_column")
105
- # output_format = arguments.get("format", "text") # Not used currently
106
-
107
- # Security validation
108
- is_valid, error_msg = self.security_validator.validate_file_path(file_path)
109
- if not is_valid:
110
- logger.warning(f"Security validation failed for file path: {file_path} - {error_msg}")
111
- raise ValueError(f"Invalid file path: {error_msg}")
112
-
113
- # Validate file exists
114
- if not Path(file_path).exists():
115
- raise FileNotFoundError(f"File not found: {file_path}")
116
-
117
- # Validate line numbers
118
- if start_line < 1:
119
- raise ValueError("start_line must be >= 1")
120
-
121
- if end_line is not None and end_line < start_line:
122
- raise ValueError("end_line must be >= start_line")
123
-
124
- # Validate column numbers
125
- if start_column is not None and start_column < 0:
126
- raise ValueError("start_column must be >= 0")
127
-
128
- if end_column is not None and end_column < 0:
129
- raise ValueError("end_column must be >= 0")
130
-
131
- logger.info(
132
- f"Reading partial content from {file_path}: lines {start_line}-{end_line or 'end'}"
133
- )
134
-
135
- try:
136
- # Use existing file_handler functionality
137
- # Use performance monitoring with proper context manager
138
- from ...mcp.utils import get_performance_monitor
139
-
140
- with get_performance_monitor().measure_operation("read_code_partial"):
141
- content = self._read_file_partial(
142
- file_path, start_line, end_line, start_column, end_column
143
- )
144
-
145
- if content is None:
146
- raise RuntimeError(
147
- f"Failed to read partial content from file: {file_path}"
148
- )
149
-
150
- # Build result structure compatible with CLI --partial-read format
151
- result_data = {
152
- "file_path": file_path,
153
- "range": {
154
- "start_line": start_line,
155
- "end_line": end_line,
156
- "start_column": start_column,
157
- "end_column": end_column,
158
- },
159
- "content": content,
160
- "content_length": len(content),
161
- }
162
-
163
- # Format as JSON string like CLI does
164
- json_output = json.dumps(result_data, indent=2, ensure_ascii=False)
165
-
166
- # Build range info for header
167
- range_info = f"Line {start_line}"
168
- if end_line:
169
- range_info += f"-{end_line}"
170
-
171
- # Build CLI-compatible output with header and JSON (without log message)
172
- cli_output = (
173
- f"--- Partial Read Result ---\n"
174
- f"File: {file_path}\n"
175
- f"Range: {range_info}\n"
176
- f"Characters read: {len(content)}\n"
177
- f"{json_output}"
178
- )
179
-
180
- logger.info(
181
- f"Successfully read {len(content)} characters from {file_path}"
182
- )
183
-
184
- return {"partial_content_result": cli_output}
185
-
186
- except Exception as e:
187
- logger.error(f"Error reading partial content from {file_path}: {e}")
188
- raise
189
-
190
- def _read_file_partial(
191
- self,
192
- file_path: str,
193
- start_line: int,
194
- end_line: int | None = None,
195
- start_column: int | None = None,
196
- end_column: int | None = None,
197
- ) -> str | None:
198
- """
199
- Internal method to read partial file content.
200
-
201
- This method wraps the existing read_file_partial function from file_handler.
202
-
203
- Args:
204
- file_path: Path to the file to read
205
- start_line: Starting line number (1-based)
206
- end_line: Ending line number (1-based, optional)
207
- start_column: Starting column number (0-based, optional)
208
- end_column: Ending column number (0-based, optional)
209
-
210
- Returns:
211
- Partial file content as string, or None if error
212
- """
213
- return read_file_partial(
214
- file_path, start_line, end_line, start_column, end_column
215
- )
216
-
217
- def validate_arguments(self, arguments: dict[str, Any]) -> bool:
218
- """
219
- Validate tool arguments against the schema.
220
-
221
- Args:
222
- arguments: Arguments to validate
223
-
224
- Returns:
225
- True if arguments are valid
226
-
227
- Raises:
228
- ValueError: If arguments are invalid
229
- """
230
- schema = self.get_tool_schema()
231
- required_fields = schema.get("required", [])
232
-
233
- # Check required fields
234
- for field in required_fields:
235
- if field not in arguments:
236
- raise ValueError(f"Required field '{field}' is missing")
237
-
238
- # Validate file_path
239
- if "file_path" in arguments:
240
- file_path = arguments["file_path"]
241
- if not isinstance(file_path, str):
242
- raise ValueError("file_path must be a string")
243
- if not file_path.strip():
244
- raise ValueError("file_path cannot be empty")
245
-
246
- # Validate start_line
247
- if "start_line" in arguments:
248
- start_line = arguments["start_line"]
249
- if not isinstance(start_line, int):
250
- raise ValueError("start_line must be an integer")
251
- if start_line < 1:
252
- raise ValueError("start_line must be >= 1")
253
-
254
- # Validate end_line
255
- if "end_line" in arguments:
256
- end_line = arguments["end_line"]
257
- if not isinstance(end_line, int):
258
- raise ValueError("end_line must be an integer")
259
- if end_line < 1:
260
- raise ValueError("end_line must be >= 1")
261
- if "start_line" in arguments and end_line < arguments["start_line"]:
262
- raise ValueError("end_line must be >= start_line")
263
-
264
- # Validate column numbers
265
- for col_field in ["start_column", "end_column"]:
266
- if col_field in arguments:
267
- col_value = arguments[col_field]
268
- if not isinstance(col_value, int):
269
- raise ValueError(f"{col_field} must be an integer")
270
- if col_value < 0:
271
- raise ValueError(f"{col_field} must be >= 0")
272
-
273
- # Validate format
274
- if "format" in arguments:
275
- format_value = arguments["format"]
276
- if not isinstance(format_value, str):
277
- raise ValueError("format must be a string")
278
- if format_value not in ["text", "json"]:
279
- raise ValueError("format must be 'text' or 'json'")
280
-
281
- return True
282
-
283
- def get_tool_definition(self) -> Any:
284
- """
285
- Get the MCP tool definition for read_code_partial.
286
-
287
- Returns:
288
- Tool definition object compatible with MCP server
289
- """
290
- try:
291
- from mcp.types import Tool
292
-
293
- return Tool(
294
- name="extract_code_section",
295
- description="Extract specific code sections by line range (equivalent to CLI --partial-read option)",
296
- inputSchema=self.get_tool_schema(),
297
- )
298
- except ImportError:
299
- # Fallback for when MCP is not available
300
- return {
301
- "name": "extract_code_section",
302
- "description": "Extract specific code sections by line range (equivalent to CLI --partial-read option)",
303
- "inputSchema": self.get_tool_schema(),
304
- }
305
-
306
-
307
- # Tool instance for easy access
308
- read_partial_tool = ReadPartialTool()
1
+ #!/usr/bin/env python3
2
+ """
3
+ Read Code Partial MCP Tool
4
+
5
+ This tool provides partial file reading functionality through the MCP protocol,
6
+ allowing selective content extraction with line and column range support.
7
+ """
8
+
9
+ import json
10
+ from pathlib import Path
11
+ from typing import Any
12
+
13
+ from ...file_handler import read_file_partial
14
+ from ...security import SecurityValidator
15
+ from ...utils import setup_logger
16
+
17
+ # Set up logging
18
+ logger = setup_logger(__name__)
19
+
20
+
21
+ class ReadPartialTool:
22
+ """
23
+ MCP Tool for reading partial content from code files.
24
+
25
+ This tool integrates with existing file_handler functionality to provide
26
+ selective file content reading through the MCP protocol.
27
+ """
28
+
29
+ def __init__(self, project_root: str = None) -> None:
30
+ """Initialize the read partial tool."""
31
+ self.security_validator = SecurityValidator(project_root)
32
+ logger.info("ReadPartialTool initialized with security validation")
33
+
34
+ def get_tool_schema(self) -> dict[str, Any]:
35
+ """
36
+ Get the MCP tool schema for read_code_partial.
37
+
38
+ Returns:
39
+ Dictionary containing the tool schema
40
+ """
41
+ return {
42
+ "type": "object",
43
+ "properties": {
44
+ "file_path": {
45
+ "type": "string",
46
+ "description": "Path to the code file to read",
47
+ },
48
+ "start_line": {
49
+ "type": "integer",
50
+ "description": "Starting line number (1-based)",
51
+ "minimum": 1,
52
+ },
53
+ "end_line": {
54
+ "type": "integer",
55
+ "description": "Ending line number (1-based, optional - reads to end if not specified)",
56
+ "minimum": 1,
57
+ },
58
+ "start_column": {
59
+ "type": "integer",
60
+ "description": "Starting column number (0-based, optional)",
61
+ "minimum": 0,
62
+ },
63
+ "end_column": {
64
+ "type": "integer",
65
+ "description": "Ending column number (0-based, optional)",
66
+ "minimum": 0,
67
+ },
68
+ "format": {
69
+ "type": "string",
70
+ "description": "Output format for the content",
71
+ "enum": ["text", "json"],
72
+ "default": "text",
73
+ },
74
+ },
75
+ "required": ["file_path", "start_line"],
76
+ "additionalProperties": False,
77
+ }
78
+
79
+ async def execute(self, arguments: dict[str, Any]) -> dict[str, Any]:
80
+ """
81
+ Execute the read_code_partial tool.
82
+
83
+ Args:
84
+ arguments: Tool arguments containing file_path, line/column ranges, and format
85
+
86
+ Returns:
87
+ Dictionary containing the partial file content and metadata (CLI --partial-read compatible format)
88
+
89
+ Raises:
90
+ ValueError: If required arguments are missing or invalid
91
+ FileNotFoundError: If the specified file doesn't exist
92
+ """
93
+ # Validate required arguments
94
+ if "file_path" not in arguments:
95
+ raise ValueError("file_path is required")
96
+
97
+ if "start_line" not in arguments:
98
+ raise ValueError("start_line is required")
99
+
100
+ file_path = arguments["file_path"]
101
+ start_line = arguments["start_line"]
102
+ end_line = arguments.get("end_line")
103
+ start_column = arguments.get("start_column")
104
+ end_column = arguments.get("end_column")
105
+ # output_format = arguments.get("format", "text") # Not used currently
106
+
107
+ # Security validation
108
+ is_valid, error_msg = self.security_validator.validate_file_path(file_path)
109
+ if not is_valid:
110
+ logger.warning(
111
+ f"Security validation failed for file path: {file_path} - {error_msg}"
112
+ )
113
+ raise ValueError(f"Invalid file path: {error_msg}")
114
+
115
+ # Validate file exists
116
+ if not Path(file_path).exists():
117
+ raise ValueError("Invalid file path: file does not exist")
118
+
119
+ # Validate line numbers
120
+ if start_line < 1:
121
+ raise ValueError("start_line must be >= 1")
122
+
123
+ if end_line is not None and end_line < start_line:
124
+ raise ValueError("end_line must be >= start_line")
125
+
126
+ # Validate column numbers
127
+ if start_column is not None and start_column < 0:
128
+ raise ValueError("start_column must be >= 0")
129
+
130
+ if end_column is not None and end_column < 0:
131
+ raise ValueError("end_column must be >= 0")
132
+
133
+ logger.info(
134
+ f"Reading partial content from {file_path}: lines {start_line}-{end_line or 'end'}"
135
+ )
136
+
137
+ try:
138
+ # Use existing file_handler functionality
139
+ # Use performance monitoring with proper context manager
140
+ from ...mcp.utils import get_performance_monitor
141
+
142
+ with get_performance_monitor().measure_operation("read_code_partial"):
143
+ content = self._read_file_partial(
144
+ file_path, start_line, end_line, start_column, end_column
145
+ )
146
+
147
+ if content is None:
148
+ raise RuntimeError(
149
+ f"Failed to read partial content from file: {file_path}"
150
+ )
151
+
152
+ # Build result structure compatible with CLI --partial-read format
153
+ result_data = {
154
+ "file_path": file_path,
155
+ "range": {
156
+ "start_line": start_line,
157
+ "end_line": end_line,
158
+ "start_column": start_column,
159
+ "end_column": end_column,
160
+ },
161
+ "content": content,
162
+ "content_length": len(content),
163
+ }
164
+
165
+ # Format as JSON string like CLI does
166
+ json_output = json.dumps(result_data, indent=2, ensure_ascii=False)
167
+
168
+ # Build range info for header
169
+ range_info = f"Line {start_line}"
170
+ if end_line:
171
+ range_info += f"-{end_line}"
172
+
173
+ # Build CLI-compatible output with header and JSON (without log message)
174
+ cli_output = (
175
+ f"--- Partial Read Result ---\n"
176
+ f"File: {file_path}\n"
177
+ f"Range: {range_info}\n"
178
+ f"Characters read: {len(content)}\n"
179
+ f"{json_output}"
180
+ )
181
+
182
+ logger.info(
183
+ f"Successfully read {len(content)} characters from {file_path}"
184
+ )
185
+
186
+ return {"partial_content_result": cli_output}
187
+
188
+ except Exception as e:
189
+ logger.error(f"Error reading partial content from {file_path}: {e}")
190
+ raise
191
+
192
+ def _read_file_partial(
193
+ self,
194
+ file_path: str,
195
+ start_line: int,
196
+ end_line: int | None = None,
197
+ start_column: int | None = None,
198
+ end_column: int | None = None,
199
+ ) -> str | None:
200
+ """
201
+ Internal method to read partial file content.
202
+
203
+ This method wraps the existing read_file_partial function from file_handler.
204
+
205
+ Args:
206
+ file_path: Path to the file to read
207
+ start_line: Starting line number (1-based)
208
+ end_line: Ending line number (1-based, optional)
209
+ start_column: Starting column number (0-based, optional)
210
+ end_column: Ending column number (0-based, optional)
211
+
212
+ Returns:
213
+ Partial file content as string, or None if error
214
+ """
215
+ return read_file_partial(
216
+ file_path, start_line, end_line, start_column, end_column
217
+ )
218
+
219
+ def validate_arguments(self, arguments: dict[str, Any]) -> bool:
220
+ """
221
+ Validate tool arguments against the schema.
222
+
223
+ Args:
224
+ arguments: Arguments to validate
225
+
226
+ Returns:
227
+ True if arguments are valid
228
+
229
+ Raises:
230
+ ValueError: If arguments are invalid
231
+ """
232
+ schema = self.get_tool_schema()
233
+ required_fields = schema.get("required", [])
234
+
235
+ # Check required fields
236
+ for field in required_fields:
237
+ if field not in arguments:
238
+ raise ValueError(f"Required field '{field}' is missing")
239
+
240
+ # Validate file_path
241
+ if "file_path" in arguments:
242
+ file_path = arguments["file_path"]
243
+ if not isinstance(file_path, str):
244
+ raise ValueError("file_path must be a string")
245
+ if not file_path.strip():
246
+ raise ValueError("file_path cannot be empty")
247
+
248
+ # Validate start_line
249
+ if "start_line" in arguments:
250
+ start_line = arguments["start_line"]
251
+ if not isinstance(start_line, int):
252
+ raise ValueError("start_line must be an integer")
253
+ if start_line < 1:
254
+ raise ValueError("start_line must be >= 1")
255
+
256
+ # Validate end_line
257
+ if "end_line" in arguments:
258
+ end_line = arguments["end_line"]
259
+ if not isinstance(end_line, int):
260
+ raise ValueError("end_line must be an integer")
261
+ if end_line < 1:
262
+ raise ValueError("end_line must be >= 1")
263
+ if "start_line" in arguments and end_line < arguments["start_line"]:
264
+ raise ValueError("end_line must be >= start_line")
265
+
266
+ # Validate column numbers
267
+ for col_field in ["start_column", "end_column"]:
268
+ if col_field in arguments:
269
+ col_value = arguments[col_field]
270
+ if not isinstance(col_value, int):
271
+ raise ValueError(f"{col_field} must be an integer")
272
+ if col_value < 0:
273
+ raise ValueError(f"{col_field} must be >= 0")
274
+
275
+ # Validate format
276
+ if "format" in arguments:
277
+ format_value = arguments["format"]
278
+ if not isinstance(format_value, str):
279
+ raise ValueError("format must be a string")
280
+ if format_value not in ["text", "json"]:
281
+ raise ValueError("format must be 'text' or 'json'")
282
+
283
+ return True
284
+
285
+ def get_tool_definition(self) -> Any:
286
+ """
287
+ Get the MCP tool definition for read_code_partial.
288
+
289
+ Returns:
290
+ Tool definition object compatible with MCP server
291
+ """
292
+ try:
293
+ from mcp.types import Tool
294
+
295
+ return Tool(
296
+ name="extract_code_section",
297
+ description="Extract specific code sections by line range (equivalent to CLI --partial-read option)",
298
+ inputSchema=self.get_tool_schema(),
299
+ )
300
+ except ImportError:
301
+ # Fallback for when MCP is not available
302
+ return {
303
+ "name": "extract_code_section",
304
+ "description": "Extract specific code sections by line range (equivalent to CLI --partial-read option)",
305
+ "inputSchema": self.get_tool_schema(),
306
+ }
307
+
308
+
309
+ # Tool instance for easy access
310
+ read_partial_tool = ReadPartialTool()