mcp-code-context 2.1.3 → 2.2.0

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.
Files changed (35) hide show
  1. package/CHANGELOG.md +44 -71
  2. package/CONTRIBUTING.md +243 -0
  3. package/MEJORAS_PROPUESTAS.md +324 -0
  4. package/README.md +31 -7
  5. package/RELEASE_NOTES_v2.2.0.md +286 -0
  6. package/dist/src/index.d.ts +36 -0
  7. package/dist/src/index.js +198 -2
  8. package/dist/src/index.js.map +1 -1
  9. package/dist/src/tools/readFileLines.d.ts +26 -0
  10. package/dist/src/tools/readFileLines.js +77 -0
  11. package/dist/src/tools/readFileLines.js.map +1 -0
  12. package/dist/src/tools/searchCodePattern.d.ts +32 -0
  13. package/dist/src/tools/searchCodePattern.js +80 -0
  14. package/dist/src/tools/searchCodePattern.js.map +1 -0
  15. package/dist/src/utils/backupManager.d.ts +13 -6
  16. package/dist/src/utils/backupManager.js +73 -8
  17. package/dist/src/utils/backupManager.js.map +1 -1
  18. package/dist/src/utils/projectRoot.d.ts +10 -0
  19. package/dist/src/utils/projectRoot.js +40 -0
  20. package/dist/src/utils/projectRoot.js.map +1 -0
  21. package/dist/tests/test-backup-system.d.ts +7 -0
  22. package/dist/tests/test-backup-system.js +152 -0
  23. package/dist/tests/test-backup-system.js.map +1 -0
  24. package/dist/tests/test-new-tools.d.ts +4 -0
  25. package/dist/tests/test-new-tools.js +147 -0
  26. package/dist/tests/test-new-tools.js.map +1 -0
  27. package/llms.txt +62 -7
  28. package/package.json +2 -2
  29. package/src/index.ts +233 -2
  30. package/src/tools/readFileLines.ts +104 -0
  31. package/src/tools/searchCodePattern.ts +129 -0
  32. package/src/utils/backupManager.ts +83 -8
  33. package/src/utils/projectRoot.ts +44 -0
  34. package/tests/test-backup-system.ts +174 -0
  35. package/tests/test-new-tools.ts +165 -0
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
4
4
  [![Tests](https://img.shields.io/badge/tests-passing-success.svg)]()
5
5
  [![TypeScript](https://img.shields.io/badge/TypeScript-100%25-blue.svg)]()
6
- [![Version](https://img.shields.io/badge/version-2.1.1-blue.svg)]()
6
+ [![Version](https://img.shields.io/badge/version-2.2.0-blue.svg)]()
7
7
 
8
8
  > MCP server that compresses any codebase into LLM-ready semantic context **and provides surgical code editing tools**. AST-based read & write for TypeScript, JavaScript, PHP, Dart & Python.
9
9
 
@@ -33,7 +33,7 @@ LLMs working with code face two bottlenecks:
33
33
 
34
34
  ## The Solution
35
35
 
36
- `mcp-code-context` provides **7 tools** — 3 for reading and 4 for writing — that operate at the **symbol level** (functions, classes, methods). Furthermore, tools support a `className` scope which correctly isolates identical symbol names in the same file (e.g. Flutter `build()` methods) to avoid reading or changing the wrong logic. Read tools extract structural skeletons. Write tools splice changes into the exact AST location.
36
+ `mcp-code-context` provides **11 tools** — 5 for reading, 1 for cleanup, and 5 for writing — that operate at the **symbol level** (functions, classes, methods). Furthermore, tools support a `className` scope which correctly isolates identical symbol names in the same file (e.g. Flutter `build()` methods) to avoid reading or changing the wrong logic. Read tools extract structural skeletons. Write tools splice changes into the exact AST location.
37
37
 
38
38
  | File | Original | Compressed | Reduction |
39
39
  |------|----------|------------|-----------|
@@ -160,18 +160,42 @@ Find all files that depend on a given file.
160
160
  - `filePath` (required) — Path to the file being modified
161
161
  - `rootDir` (optional) — Repository root (auto-detected)
162
162
 
163
- #### 4. `rollback_file`
163
+ #### 4. `read_file_lines`
164
+ Read specific line ranges from a file without loading the entire content. More efficient than `read_file_surgical` for small fragments.
165
+ - `filePath` (required) — Path to the source file
166
+ - `startLine` (optional) — Starting line number (1-indexed)
167
+ - `endLine` (optional) — Ending line number (1-indexed)
168
+ - `aroundPattern` (optional) — Search pattern to find and return surrounding lines
169
+ - `contextLines` (optional) — Number of lines before/after pattern (default: 5)
170
+
171
+ #### 5. `search_code_pattern`
172
+ Search for code patterns across multiple files with context. Respects `.gitignore` rules.
173
+ - `rootDir` (required) — Repository root directory
174
+ - `pattern` (required) — Regular expression pattern to search
175
+ - `fileExtensions` (optional) — Array of extensions to search (e.g., `[".ts", ".dart"]`)
176
+ - `excludeDirs` (optional) — Directories to exclude (default: `["node_modules", "dist", "build"]`)
177
+ - `showContext` (optional) — Include surrounding lines (default: true)
178
+ - `contextLines` (optional) — Number of context lines (default: 3)
179
+ - `maxResults` (optional) — Maximum matches to return (default: 50)
180
+
181
+ #### 6. `rollback_file`
164
182
  Surgically restore a file to a previous state from the automated backup system.
165
183
  - `filePath` (required) — Path to the file to restore
166
184
  - `steps` (optional) — Number of versions to go back (1-5, default: 1)
167
185
 
186
+ #### 7. `clean_backups`
187
+ Remove all backup files for a project to keep the working directory clean.
188
+ - `projectRoot` (required) — Absolute path to the project root
189
+
190
+ **Note:** Backups are stored centrally at `[project-root]/.mcp-backups/` to keep your project organized.
191
+
168
192
  ### Write Tools (Phase 1: Preview)
169
193
 
170
194
  All write tools follow a **Two-Phase Workflow**:
171
195
  1. **Call without token**: Returns a unified `diff` and a `confirmationToken`.
172
196
  2. **Call with token**: Set `confirm: true` and provide the token to apply the changes.
173
197
 
174
- #### 5. `write_file_surgical`
198
+ #### 7. `write_file_surgical`
175
199
  Replace the full source code of a named symbol in a file.
176
200
  - `filePath` (required) — Path to the file
177
201
  - `symbolName` (required) — Symbol to replace
@@ -180,7 +204,7 @@ Replace the full source code of a named symbol in a file.
180
204
  - `confirm` (optional) — Set to `true` to apply
181
205
  - `className` (optional) — Scope the symbol to a specific class
182
206
 
183
- #### 5. `insert_symbol`
207
+ #### 8. `insert_symbol`
184
208
  Insert new code at a precise location relative to an existing symbol.
185
209
  - `filePath` (required) — Path to the file
186
210
  - `code` (required) — Code to insert
@@ -189,7 +213,7 @@ Insert new code at a precise location relative to an existing symbol.
189
213
  - `className` (optional) — Scope the anchor to a specific class
190
214
  - `confirmationToken`, `confirm` (optional)
191
215
 
192
- #### 6. `rename_symbol`
216
+ #### 9. `rename_symbol`
193
217
  Rename a symbol across the entire repository (definition + all usages).
194
218
  - `filePath` (required) — File where the symbol is defined
195
219
  - `oldName` (required) — Current name
@@ -197,7 +221,7 @@ Rename a symbol across the entire repository (definition + all usages).
197
221
  - `rootDir` (optional) — Repository root
198
222
  - `confirmationToken`, `confirm` (optional)
199
223
 
200
- #### 7. `remove_symbol`
224
+ #### 10. `remove_symbol`
201
225
  Safely remove a symbol from a file with dependency checking.
202
226
  - `filePath` (required) — Path to the file
203
227
  - `symbolName` (required) — Symbol to remove
@@ -0,0 +1,286 @@
1
+ # 🚀 Release v2.2.0 - Centralized Backup System + New Read Tools
2
+
3
+ **Release Date:** April 22, 2026
4
+ **Type:** Minor Release (New Features + Improvements)
5
+
6
+ ---
7
+
8
+ ## 🎯 What's New
9
+
10
+ ### 1. 📖 **New Read Tools** (Token Efficiency Champions)
11
+
12
+ #### `read_file_lines` - Surgical Line Reading
13
+ Read specific line ranges or search around patterns without loading entire files.
14
+
15
+ **Use Cases:**
16
+ - Debug specific code blocks
17
+ - View error context from stack traces
18
+ - Inspect method implementations without full file overhead
19
+
20
+ **Token Savings:** ~90% compared to reading full files
21
+
22
+ **Examples:**
23
+ ```typescript
24
+ // Read exact range
25
+ read_file_lines({
26
+ filePath: "/project/src/utils.ts",
27
+ startLine: 120,
28
+ endLine: 135
29
+ })
30
+
31
+ // Search around pattern
32
+ read_file_lines({
33
+ filePath: "/project/src/service.ts",
34
+ aroundPattern: "calculateTotal",
35
+ contextLines: 5
36
+ })
37
+ ```
38
+
39
+ #### `search_code_pattern` - Repository-Wide Pattern Search
40
+ Find patterns across your codebase with context, respecting `.gitignore`.
41
+
42
+ **Use Cases:**
43
+ - Find all usages of a function
44
+ - Locate TODO comments
45
+ - Search for specific patterns with context
46
+
47
+ **Token Savings:** ~85% compared to manual grep workflows
48
+
49
+ **Examples:**
50
+ ```typescript
51
+ search_code_pattern({
52
+ rootDir: "/project",
53
+ pattern: "widget\\.height",
54
+ fileExtensions: [".dart"],
55
+ showContext: true,
56
+ maxResults: 20
57
+ })
58
+ ```
59
+
60
+ ---
61
+
62
+ ### 2. 🧹 **Centralized Backup System** (Major Improvement)
63
+
64
+ **Problem Solved:** Backups were scattered throughout projects, polluting git status and creating multiple `.mcp-backups/` folders.
65
+
66
+ **Solution:** ONE centralized backup directory at project root.
67
+
68
+ #### Before (v2.1.x):
69
+ ```
70
+ project/
71
+ ├── lib/
72
+ │ ├── screens/
73
+ │ │ └── .mcp-backups/ ❌
74
+ │ └── services/
75
+ │ └── .mcp-backups/ ❌
76
+ └── src/
77
+ └── .mcp-backups/ ❌
78
+ ```
79
+
80
+ #### After (v2.2.0):
81
+ ```
82
+ project/
83
+ ├── .mcp-backups/ ✅ ONE directory
84
+ │ ├── lib/
85
+ │ │ ├── screens/
86
+ │ │ └── services/
87
+ │ └── src/
88
+ ├── lib/
89
+ ├── services/
90
+ └── src/
91
+ ```
92
+
93
+ **Benefits:**
94
+ - ✅ Clean git status
95
+ - ✅ Easy to clean all backups at once
96
+ - ✅ Preserves internal folder structure
97
+ - ✅ Backward compatible
98
+
99
+ #### `clean_backups` - New Cleanup Tool
100
+ Remove all backups with a single command.
101
+
102
+ ```typescript
103
+ clean_backups({
104
+ projectRoot: "/path/to/project"
105
+ })
106
+ ```
107
+
108
+ ---
109
+
110
+ ## 📊 Technical Improvements
111
+
112
+ ### Test Coverage
113
+ - **148 tests passing** (100% success rate)
114
+ - 35 Dart compression tests
115
+ - 33 PHP compression tests
116
+ - 59 Surgical writing tests
117
+ - 7 New tools tests
118
+ - 7 Backup system tests
119
+ - 7 Integration tests
120
+
121
+ ### Performance
122
+ - `read_file_lines`: 90% token reduction vs full file reads
123
+ - `search_code_pattern`: 85% more efficient than manual grep
124
+ - Centralized backups: 0 scattered directories
125
+
126
+ ### Reliability
127
+ - Comprehensive error handling
128
+ - Edge case coverage (deep nesting, non-existent paths)
129
+ - Backward compatible with legacy backup locations
130
+
131
+ ---
132
+
133
+ ## 🛠️ All Tools (11 Total)
134
+
135
+ ### Read Tools (5)
136
+ 1. `get_semantic_repo_map` - Repository structure overview
137
+ 2. `read_file_surgical` - Extract specific symbols
138
+ 3. `analyze_impact` - Find dependencies
139
+ 4. **`read_file_lines`** - Read line ranges ⭐ NEW
140
+ 5. **`search_code_pattern`** - Search with context ⭐ NEW
141
+
142
+ ### Cleanup Tools (1)
143
+ 6. **`clean_backups`** - Remove all backups ⭐ NEW
144
+
145
+ ### Write Tools (5)
146
+ 7. `write_file_surgical` - Replace symbols
147
+ 8. `insert_symbol` - Insert code precisely
148
+ 9. `rename_symbol` - Rename across repository
149
+ 10. `remove_symbol` - Safe symbol removal
150
+ 11. `rollback_file` - Undo changes
151
+
152
+ ---
153
+
154
+ ## 📦 Installation
155
+
156
+ ### NPM (Recommended)
157
+ ```bash
158
+ npm install -g mcp-code-context@2.2.0
159
+ ```
160
+
161
+ ### From Source
162
+ ```bash
163
+ git clone https://github.com/achatainga/mcp-code-context.git
164
+ cd mcp-code-context
165
+ git checkout v2.2.0
166
+ npm install
167
+ npm run build
168
+ ```
169
+
170
+ ---
171
+
172
+ ## ⚙️ Configuration
173
+
174
+ ### Amazon Q / VS Code / Cursor
175
+ Add to your MCP config:
176
+
177
+ ```json
178
+ {
179
+ "mcpServers": {
180
+ "code-context": {
181
+ "command": "npx",
182
+ "args": ["-y", "mcp-code-context@2.2.0"]
183
+ }
184
+ }
185
+ }
186
+ ```
187
+
188
+ ### Claude Desktop
189
+ Add to `claude_desktop_config.json`:
190
+
191
+ ```json
192
+ {
193
+ "mcpServers": {
194
+ "code-context": {
195
+ "command": "npx",
196
+ "args": ["-y", "mcp-code-context@2.2.0"]
197
+ }
198
+ }
199
+ }
200
+ ```
201
+
202
+ ---
203
+
204
+ ## 🔄 Migration from v2.1.x
205
+
206
+ ### Automatic Migration
207
+ No action needed! The new backup system:
208
+ - ✅ Automatically uses centralized location for new backups
209
+ - ✅ Still reads legacy backup locations
210
+ - ✅ No breaking changes
211
+
212
+ ### Optional Cleanup
213
+ Clean old scattered backups:
214
+
215
+ ```bash
216
+ # Find old backup directories
217
+ find . -type d -name ".mcp-backups" -not -path "./.mcp-backups"
218
+
219
+ # Remove them (after verifying)
220
+ find . -type d -name ".mcp-backups" -not -path "./.mcp-backups" -exec rm -rf {} +
221
+ ```
222
+
223
+ ---
224
+
225
+ ## 🐛 Bug Fixes
226
+
227
+ - Fixed backup directory pollution in git status
228
+ - Improved error messages for non-existent paths
229
+ - Better handling of deeply nested file structures
230
+
231
+ ---
232
+
233
+ ## 📚 Documentation
234
+
235
+ - [README.md](README.md) - Complete tool documentation
236
+ - [CHANGELOG.md](CHANGELOG.md) - Detailed change history
237
+ - [CONTRIBUTING.md](CONTRIBUTING.md) - Contribution guidelines
238
+ - [llms.txt](llms.txt) - AI-optimized documentation
239
+
240
+ ---
241
+
242
+ ## 🙏 Acknowledgments
243
+
244
+ This release was built based on real-world debugging experience with:
245
+ - Flutter/Dart projects (DeTodo24 mobile app)
246
+ - WordPress/PHP backends (dt24-home-engine)
247
+ - Complex multi-repository architectures
248
+
249
+ Special thanks to the community for feedback and testing.
250
+
251
+ ---
252
+
253
+ ## 📈 What's Next (v2.3.0)
254
+
255
+ Planned features:
256
+ - `extract_json_value` - Parse JSON responses efficiently
257
+ - Enhanced `get_semantic_repo_map` with file limits
258
+ - Support for more languages (Go, Rust, Java)
259
+ - Performance optimizations for large repositories
260
+
261
+ ---
262
+
263
+ ## 🔗 Links
264
+
265
+ - **GitHub:** https://github.com/achatainga/mcp-code-context
266
+ - **NPM:** https://www.npmjs.com/package/mcp-code-context
267
+ - **Issues:** https://github.com/achatainga/mcp-code-context/issues
268
+ - **Discussions:** https://github.com/achatainga/mcp-code-context/discussions
269
+
270
+ ---
271
+
272
+ ## 📄 License
273
+
274
+ MIT License - See [LICENSE](LICENSE) for details
275
+
276
+ ---
277
+
278
+ **Full Changelog:** https://github.com/achatainga/mcp-code-context/compare/v2.1.3...v2.2.0
279
+
280
+ ---
281
+
282
+ *Built with ❤️ for the AI-assisted development community*
283
+
284
+ **Version:** 2.2.0
285
+ **Released:** April 22, 2026
286
+ **Tested:** 148/148 tests passing ✅
@@ -115,3 +115,39 @@ export declare function handleRollbackFile(args: Record<string, unknown>): Promi
115
115
  text: string;
116
116
  }[];
117
117
  }>;
118
+ export declare function handleCleanBackups(args: Record<string, unknown>): Promise<{
119
+ content: {
120
+ type: "text";
121
+ text: string;
122
+ }[];
123
+ isError: boolean;
124
+ } | {
125
+ content: {
126
+ type: "text";
127
+ text: string;
128
+ }[];
129
+ }>;
130
+ export declare function handleReadFileLines(args: Record<string, unknown>): Promise<{
131
+ content: {
132
+ type: "text";
133
+ text: string;
134
+ }[];
135
+ isError: boolean;
136
+ } | {
137
+ content: {
138
+ type: "text";
139
+ text: string;
140
+ }[];
141
+ }>;
142
+ export declare function handleSearchCodePattern(args: Record<string, unknown>): Promise<{
143
+ content: {
144
+ type: "text";
145
+ text: string;
146
+ }[];
147
+ isError: boolean;
148
+ } | {
149
+ content: {
150
+ type: "text";
151
+ text: string;
152
+ }[];
153
+ }>;
package/dist/src/index.js CHANGED
@@ -26,14 +26,16 @@ import { IgnoreManager } from "./utils/ignoreManager.js";
26
26
  import { compressFile, extractSymbol } from "./ast/semanticCompressor.js";
27
27
  import { replaceSymbol, insertCode, renameInFile, renameReferencesInFile, removeSymbolFromFile, WRITABLE_EXTENSIONS, } from "./ast/writers/symbolWriter.js";
28
28
  import { generateDiff, generateMultiFileDiff } from "./utils/diffEngine.js";
29
- import { createBackup, restoreBackup } from "./utils/backupManager.js";
29
+ import { createBackup, restoreBackup, cleanAllBackups } from "./utils/backupManager.js";
30
30
  import { extractFallbackSymbols, findClosestSymbols } from "./utils/fuzzyMatch.js";
31
31
  import { confirmationCache } from "./utils/confirmationCache.js";
32
+ import { readFileLines } from "./tools/readFileLines.js";
33
+ import { searchCodePattern } from "./tools/searchCodePattern.js";
32
34
  import * as fs from "node:fs";
33
35
  import * as path from "node:path";
34
36
  // ─── Constants ──────────────────────────────────────────────────────
35
37
  const SERVER_NAME = "mcp-code-context";
36
- const SERVER_VERSION = "2.0.0";
38
+ const SERVER_VERSION = "2.2.0";
37
39
  /** Extensions we consider source code for analysis */
38
40
  const SOURCE_EXTENSIONS = new Set([
39
41
  ".ts", ".tsx", ".js", ".jsx", ".mts", ".mjs", ".cts", ".cjs",
@@ -136,6 +138,104 @@ const TOOLS = [
136
138
  required: ["filePath"],
137
139
  },
138
140
  },
141
+ {
142
+ name: "clean_backups",
143
+ description: "Removes all backup files for a project. Deletes the entire .mcp-backups directory " +
144
+ "at the project root, freeing up disk space and cleaning the working directory. " +
145
+ "Use this to clean up after completing a series of edits or when backups are no longer needed.",
146
+ inputSchema: {
147
+ type: "object",
148
+ properties: {
149
+ projectRoot: {
150
+ type: "string",
151
+ description: "Absolute path to the project root directory. The .mcp-backups folder " +
152
+ "at this location will be removed.",
153
+ },
154
+ },
155
+ required: ["projectRoot"],
156
+ },
157
+ },
158
+ {
159
+ name: "read_file_lines",
160
+ description: "Reads specific line ranges from a file without loading the entire content. " +
161
+ "Supports reading by exact line range (startLine/endLine) or around a pattern match. " +
162
+ "More efficient than read_file_surgical when you only need a small fragment of code. " +
163
+ "Perfect for debugging, viewing specific code blocks, or extracting context around errors.",
164
+ inputSchema: {
165
+ type: "object",
166
+ properties: {
167
+ filePath: {
168
+ type: "string",
169
+ description: "Absolute path to the source file to read.",
170
+ },
171
+ startLine: {
172
+ type: "number",
173
+ description: "Starting line number (1-indexed). Required if using exact range mode.",
174
+ },
175
+ endLine: {
176
+ type: "number",
177
+ description: "Ending line number (1-indexed). Required if using exact range mode.",
178
+ },
179
+ aroundPattern: {
180
+ type: "string",
181
+ description: "Search pattern to find in the file. Returns lines around the first match. " +
182
+ "Use this mode when you don't know the exact line numbers.",
183
+ },
184
+ contextLines: {
185
+ type: "number",
186
+ description: "Number of lines to include before and after the pattern match. " +
187
+ "Defaults to 5. Only used with aroundPattern mode.",
188
+ },
189
+ },
190
+ required: ["filePath"],
191
+ },
192
+ },
193
+ {
194
+ name: "search_code_pattern",
195
+ description: "Searches for code patterns across multiple files in a repository. " +
196
+ "Returns matches with file paths, line numbers, and optional context lines. " +
197
+ "Respects .gitignore rules and allows filtering by file extensions. " +
198
+ "More efficient than manual grep when you need structured results with context.",
199
+ inputSchema: {
200
+ type: "object",
201
+ properties: {
202
+ rootDir: {
203
+ type: "string",
204
+ description: "Absolute path to the repository root directory to search.",
205
+ },
206
+ pattern: {
207
+ type: "string",
208
+ description: "Regular expression pattern to search for. Use proper regex escaping " +
209
+ "(e.g., 'widget\\\\.height' to match 'widget.height').",
210
+ },
211
+ fileExtensions: {
212
+ type: "array",
213
+ items: { type: "string" },
214
+ description: "Array of file extensions to search (e.g., ['.ts', '.dart', '.py']). " +
215
+ "Defaults to common code extensions if omitted.",
216
+ },
217
+ excludeDirs: {
218
+ type: "array",
219
+ items: { type: "string" },
220
+ description: "Array of directory names to exclude (e.g., ['node_modules', 'dist']). " +
221
+ "Defaults to common build/dependency directories.",
222
+ },
223
+ showContext: {
224
+ type: "boolean",
225
+ description: "If true, includes surrounding lines for each match. Defaults to true.",
226
+ },
227
+ contextLines: {
228
+ type: "number",
229
+ description: "Number of context lines before/after each match. Defaults to 3.",
230
+ },
231
+ maxResults: {
232
+ type: "number",
233
+ description: "Maximum number of matches to return. Defaults to 50.",
234
+ },
235
+ },
236
+ required: ["rootDir", "pattern"],
237
+ },
238
+ },
139
239
  {
140
240
  name: "analyze_impact",
141
241
  description: "Analyzes the impact of modifying a given file by discovering all other " +
@@ -363,6 +463,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
363
463
  return await handleRemoveSymbol(args);
364
464
  case "rollback_file":
365
465
  return await handleRollbackFile(args);
466
+ case "clean_backups":
467
+ return await handleCleanBackups(args);
468
+ case "read_file_lines":
469
+ return await handleReadFileLines(args);
470
+ case "search_code_pattern":
471
+ return await handleSearchCodePattern(args);
366
472
  default:
367
473
  return errorResponse(`Unknown tool: "${name}"`);
368
474
  }
@@ -1267,6 +1373,96 @@ export async function handleRollbackFile(args) {
1267
1373
  }],
1268
1374
  };
1269
1375
  }
1376
+ export async function handleCleanBackups(args) {
1377
+ const projectRoot = args.projectRoot;
1378
+ if (!projectRoot)
1379
+ return errorResponse("Missing required parameter: projectRoot");
1380
+ const resolvedPath = path.resolve(projectRoot);
1381
+ if (!fs.existsSync(resolvedPath)) {
1382
+ return errorResponse(`Project root not found: ${resolvedPath}`);
1383
+ }
1384
+ const success = cleanAllBackups(resolvedPath);
1385
+ if (!success) {
1386
+ return {
1387
+ content: [{
1388
+ type: "text",
1389
+ text: `// ℹ️ No backups found\n// No .mcp-backups directory exists at: ${resolvedPath}`,
1390
+ }],
1391
+ };
1392
+ }
1393
+ return {
1394
+ content: [{
1395
+ type: "text",
1396
+ text: `// 🧹 Cleanup successful!\n// Removed all backups from: ${resolvedPath}/.mcp-backups\n// Your project is now clean.`,
1397
+ }],
1398
+ };
1399
+ }
1400
+ // ─── Tool: read_file_lines ──────────────────────────────────────────
1401
+ export async function handleReadFileLines(args) {
1402
+ const result = readFileLines(args);
1403
+ if (!result.success) {
1404
+ return errorResponse(result.error || "Unknown error reading file lines");
1405
+ }
1406
+ const { content, lineRange } = result;
1407
+ const header = lineRange
1408
+ ? `// Lines ${lineRange.start}-${lineRange.end}\n// File: ${args.filePath}\n\n`
1409
+ : `// File: ${args.filePath}\n\n`;
1410
+ return {
1411
+ content: [
1412
+ {
1413
+ type: "text",
1414
+ text: header + content,
1415
+ },
1416
+ ],
1417
+ };
1418
+ }
1419
+ // ─── Tool: search_code_pattern ──────────────────────────────────────
1420
+ export async function handleSearchCodePattern(args) {
1421
+ const result = searchCodePattern(args);
1422
+ if (!result.success) {
1423
+ return errorResponse(result.error || "Unknown error searching code");
1424
+ }
1425
+ const { matches, totalMatches } = result;
1426
+ if (!matches || matches.length === 0) {
1427
+ return {
1428
+ content: [
1429
+ {
1430
+ type: "text",
1431
+ text: `# Search Results\n\nNo matches found for pattern: "${args.pattern}"`,
1432
+ },
1433
+ ],
1434
+ };
1435
+ }
1436
+ const lines = [
1437
+ `# Search Results`,
1438
+ ``,
1439
+ `**Pattern:** \`${args.pattern}\``,
1440
+ `**Root:** \`${args.rootDir}\``,
1441
+ `**Matches:** ${totalMatches} (showing ${matches.length})`,
1442
+ ``,
1443
+ ];
1444
+ for (const match of matches) {
1445
+ lines.push(`## \`${match.file}\` (line ${match.lineNumber})`);
1446
+ lines.push(``);
1447
+ if (match.context) {
1448
+ lines.push("```");
1449
+ lines.push(...match.context);
1450
+ lines.push("```");
1451
+ }
1452
+ else {
1453
+ lines.push(`\`\`\`\n${match.line}\n\`\`\``);
1454
+ }
1455
+ lines.push(``);
1456
+ }
1457
+ return {
1458
+ content: [
1459
+ {
1460
+ type: "text",
1461
+ text: lines.join("\n"),
1462
+ },
1463
+ ],
1464
+ };
1465
+ }
1270
1466
  function errorResponse(message) {
1271
1467
  return {
1272
1468
  content: [{ type: "text", text: `❌ ${message}` }],