fileditor-mcp 1.0.2 → 1.0.3

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.
@@ -1,26 +1,26 @@
1
- import { FileUtils } from '../utils/fileUtils.js';
2
-
3
- /**
4
- * set_workspace tool handler
5
- */
6
- export class SetWorkspaceHandler {
7
-
8
- /**
9
- * Handle set_workspace request
10
- * @param {Object} args - Request parameters
11
- * @returns {Promise<Object>} Response result
12
- */
13
- static async handle(args) {
14
- const { path } = args;
15
-
16
- try {
17
- // Set new workspace root directory
18
- FileUtils.setWorkspaceRoot(path);
19
-
20
- const message = `Successfully set workspace root to: ${FileUtils.getWorkspaceRoot()}`;
21
- return FileUtils.createResponse(message);
22
- } catch (error) {
23
- throw new Error(`Failed to set workspace: ${error.message}`);
24
- }
25
- }
26
- }
1
+ import { FileUtils } from '../utils/fileUtils.js';
2
+
3
+ /**
4
+ * set_workspace tool handler
5
+ */
6
+ export class SetWorkspaceHandler {
7
+
8
+ /**
9
+ * Handle set_workspace request
10
+ * @param {Object} args - Request parameters
11
+ * @returns {Promise<Object>} Response result
12
+ */
13
+ static async handle(args) {
14
+ const { path } = args;
15
+
16
+ try {
17
+ // Set new workspace root directory
18
+ FileUtils.setWorkspaceRoot(path);
19
+
20
+ const message = `Successfully set workspace root to: ${FileUtils.getWorkspaceRoot()}`;
21
+ return FileUtils.createResponse(message);
22
+ } catch (error) {
23
+ throw new Error(`Failed to set workspace: ${error.message}`);
24
+ }
25
+ }
26
+ }
@@ -1,92 +1,98 @@
1
- import { FileUtils } from '../utils/fileUtils.js';
2
-
3
- /**
4
- * write_files tool handler
5
- */
6
- export class WriteFileHandler {
7
-
8
- /**
9
- * Handle write_files request
10
- * @param {Object} args - Request parameters
11
- * @returns {Promise<Object>} Response result
12
- */
13
- static async handle(args) {
14
- const { path, content, line_count } = args;
15
-
16
- try {
17
- // Use FileUtils to normalize parameters
18
- const { paths, contents, lineCounts, fileCount } = FileUtils.normalizeMultiFileArgs(args);
19
-
20
- const results = [];
21
- const writeOperations = [];
22
- const warnings = [];
23
-
24
- // Perform all write operations
25
- for (let i = 0; i < fileCount; i++) {
26
- const filePath = paths[i];
27
- const fileContent = contents[i];
28
- const expectedLines = lineCounts[i];
29
-
30
- // Execute write operations in parallel
31
- writeOperations.push(
32
- FileUtils.writeFile(filePath, fileContent).then(() => {
33
- // Validate line count
34
- const actualLines = FileUtils.countLines(fileContent);
35
- if (expectedLines !== null && actualLines !== expectedLines) {
36
- warnings.push(`${filePath} - Expected ${expectedLines} lines, but got ${actualLines} lines`);
37
- }
38
-
39
- return {
40
- path: filePath,
41
- actualLines,
42
- expectedLines,
43
- success: true
44
- };
45
- }).catch(error => {
46
- return {
47
- path: filePath,
48
- success: false,
49
- error: error.message
50
- };
51
- })
52
- );
53
- }
54
-
55
- // Wait for all write operations to complete
56
- const writeResults = await Promise.all(writeOperations);
57
-
58
- // Check for failed operations
59
- const failures = writeResults.filter(result => !result.success);
60
- if (failures.length > 0) {
61
- const errorMessages = failures.map(f => `${f.path}: ${f.error}`);
62
- throw new Error(`Failed to write ${failures.length} file(s): ${errorMessages.join(', ')}`);
63
- }
64
-
65
- // Build success message
66
- const successResults = writeResults.filter(result => result.success);
67
- const totalFiles = successResults.length;
68
- const totalLines = successResults.reduce((sum, result) => sum + result.actualLines, 0);
69
-
70
- let message;
71
- if (totalFiles === 1) {
72
- const result = successResults[0];
73
- message = `File written successfully: ${result.path} (${result.actualLines} lines)`;
74
- } else {
75
- message = `Successfully wrote ${totalFiles} files (${totalLines} total lines):\n` +
76
- successResults.map(result =>
77
- ` - ${result.path} (${result.actualLines} lines)`
78
- ).join('\n');
79
- }
80
-
81
- // Add warnings to the message if any
82
- if (warnings.length > 0) {
83
- message += '\n\nWarnings:\n' + warnings.map(w => ` ⚠️ ${w}`).join('\n');
84
- }
85
-
86
- return FileUtils.createResponse(message);
87
-
88
- } catch (error) {
89
- throw new Error(`Failed to write file(s): ${error.message}`);
90
- }
91
- }
1
+ import { FileUtils } from '../utils/fileUtils.js';
2
+
3
+ /**
4
+ * write_files tool handler
5
+ */
6
+ export class WriteFileHandler {
7
+
8
+ /**
9
+ * Handle write_files request
10
+ * @param {Object} args - Request parameters
11
+ * @returns {Promise<Object>} Response result
12
+ */
13
+ static async handle(args) {
14
+ const { path, content, line_count } = args;
15
+
16
+ try {
17
+ // Handle single file or multiple files
18
+ const paths = Array.isArray(path) ? path : [path];
19
+ const contents = Array.isArray(content) ? content : [content];
20
+ const lineCounts = Array.isArray(line_count) ? line_count : [line_count];
21
+
22
+ // Validate array length consistency
23
+ if (Array.isArray(path)) {
24
+ if (Array.isArray(content) && contents.length !== paths.length) {
25
+ throw new Error(`Path count (${paths.length}) doesn't match content count (${contents.length})`);
26
+ }
27
+ if (Array.isArray(line_count) && lineCounts.length !== paths.length) {
28
+ throw new Error(`Path count (${paths.length}) doesn't match line_count array length (${lineCounts.length})`);
29
+ }
30
+ }
31
+
32
+ const results = [];
33
+ const writeOperations = [];
34
+
35
+ // Perform all write operations
36
+ for (let i = 0; i < paths.length; i++) {
37
+ const filePath = paths[i];
38
+ const fileContent = Array.isArray(content) ? contents[i] : content;
39
+ const expectedLines = Array.isArray(line_count) ? lineCounts[i] : line_count;
40
+
41
+ // Execute write operations in parallel
42
+ writeOperations.push(
43
+ FileUtils.writeFile(filePath, fileContent).then(() => {
44
+ // Validate line count
45
+ const actualLines = FileUtils.countLines(fileContent);
46
+ if (actualLines !== expectedLines) {
47
+ console.warn(`Warning: ${filePath} - Expected ${expectedLines} lines, but got ${actualLines} lines`);
48
+ }
49
+
50
+ return {
51
+ path: filePath,
52
+ actualLines,
53
+ expectedLines,
54
+ success: true
55
+ };
56
+ }).catch(error => {
57
+ return {
58
+ path: filePath,
59
+ success: false,
60
+ error: error.message
61
+ };
62
+ })
63
+ );
64
+ }
65
+
66
+ // Wait for all write operations to complete
67
+ const writeResults = await Promise.all(writeOperations);
68
+
69
+ // Check for failed operations
70
+ const failures = writeResults.filter(result => !result.success);
71
+ if (failures.length > 0) {
72
+ const errorMessages = failures.map(f => `${f.path}: ${f.error}`);
73
+ throw new Error(`Failed to write ${failures.length} file(s): ${errorMessages.join(', ')}`);
74
+ }
75
+
76
+ // Build success message
77
+ const successResults = writeResults.filter(result => result.success);
78
+ const totalFiles = successResults.length;
79
+ const totalLines = successResults.reduce((sum, result) => sum + result.actualLines, 0);
80
+
81
+ let message;
82
+ if (totalFiles === 1) {
83
+ const result = successResults[0];
84
+ message = `File written successfully: ${result.path} (${result.actualLines} lines)`;
85
+ } else {
86
+ message = `Successfully wrote ${totalFiles} files (${totalLines} total lines):\n` +
87
+ successResults.map(result =>
88
+ ` - ${result.path} (${result.actualLines} lines)`
89
+ ).join('\n');
90
+ }
91
+
92
+ return FileUtils.createResponse(message);
93
+
94
+ } catch (error) {
95
+ throw new Error(`Failed to write file(s): ${error.message}`);
96
+ }
97
+ }
92
98
  }
package/src/index.js CHANGED
@@ -1,22 +1,22 @@
1
- #!/usr/bin/env node
2
-
3
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
- import { FileEditorMCPServer } from './server.js';
5
-
6
- /**
7
- * Entry point for FileEditor MCP server
8
- */
9
- async function main() {
10
- try {
11
- const server = new FileEditorMCPServer();
12
- const transport = new StdioServerTransport();
13
-
14
- await server.start(transport);
15
- } catch (error) {
16
- console.error("Failed to start FileEditor MCP server:", error);
17
- process.exit(1);
18
- }
19
- }
20
-
21
- // Start the server
22
- main();
1
+ #!/usr/bin/env node
2
+
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { FileEditorMCPServer } from './server.js';
5
+
6
+ /**
7
+ * Entry point for FileEditor MCP server
8
+ */
9
+ async function main() {
10
+ try {
11
+ const server = new FileEditorMCPServer();
12
+ const transport = new StdioServerTransport();
13
+
14
+ await server.start(transport);
15
+ } catch (error) {
16
+ console.error("Failed to start FileEditor MCP server:", error);
17
+ process.exit(1);
18
+ }
19
+ }
20
+
21
+ // Start the server
22
+ main();
package/src/server.js CHANGED
@@ -1,85 +1,85 @@
1
- import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
- import {
3
- CallToolRequestSchema,
4
- ListToolsRequestSchema,
5
- } from "@modelcontextprotocol/sdk/types.js";
6
-
7
- import { toolDefinitions } from './tools/toolDefinitions.js';
8
- import { SetWorkspaceHandler } from './handlers/setWorkspace.js';
9
- import { ReadFileHandler } from './handlers/readFile.js';
10
- import { WriteFileHandler } from './handlers/writeFile.js';
11
- import { ListFilesHandler } from './handlers/listFiles.js';
12
- import { InsertContentHandler } from './handlers/insertContent.js';
13
- import { ApplyDiffHandler } from './handlers/applyDiff.js';
14
- import { SearchAndReplaceHandler } from './handlers/searchAndReplace.js';
15
- import { FileUtils } from './utils/fileUtils.js';
16
-
17
- /**
18
- * Main class for FileEditor MCP server
19
- */
20
- export class FileEditorMCPServer {
21
- constructor() {
22
- this.server = new Server(
23
- {
24
- name: "fileditor-mcp",
25
- version: "1.0.0",
26
- },
27
- {
28
- capabilities: {
29
- tools: {},
30
- },
31
- }
32
- );
33
-
34
- this.setupHandlers();
35
- }
36
-
37
- /**
38
- * Set up request handlers
39
- */
40
- setupHandlers() {
41
- // List available tools
42
- this.server.setRequestHandler(ListToolsRequestSchema, async () => {
43
- return {
44
- tools: toolDefinitions
45
- };
46
- });
47
-
48
- // Handle tool calls
49
- this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
50
- try {
51
- const { name, arguments: args } = request.params;
52
-
53
- switch (name) {
54
- case "set_workspace":
55
- return await SetWorkspaceHandler.handle(args);
56
- case "read_files":
57
- return await ReadFileHandler.handle(args);
58
- case "write_files":
59
- return await WriteFileHandler.handle(args);
60
- case "list_files":
61
- return await ListFilesHandler.handle(args);
62
- case "insert_contents":
63
- return await InsertContentHandler.handle(args);
64
- case "apply_diffs":
65
- return await ApplyDiffHandler.handle(args);
66
- case "search_and_replace":
67
- return await SearchAndReplaceHandler.handle(args);
68
- default:
69
- throw new Error(`Unknown tool: ${name}`);
70
- }
71
- } catch (error) {
72
- return FileUtils.createErrorResponse(error.message);
73
- }
74
- });
75
- }
76
-
77
- /**
78
- * Start the server
79
- * @param {Object} transport - Transport object
80
- */
81
- async start(transport) {
82
- await this.server.connect(transport);
83
- console.error("FileEditor MCP server running on stdio");
84
- }
85
- }
1
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
+ import {
3
+ CallToolRequestSchema,
4
+ ListToolsRequestSchema,
5
+ } from "@modelcontextprotocol/sdk/types.js";
6
+
7
+ import { toolDefinitions } from './tools/toolDefinitions.js';
8
+ import { SetWorkspaceHandler } from './handlers/setWorkspace.js';
9
+ import { ReadFileHandler } from './handlers/readFile.js';
10
+ import { WriteFileHandler } from './handlers/writeFile.js';
11
+ import { ListFilesHandler } from './handlers/listFiles.js';
12
+ import { InsertContentHandler } from './handlers/insertContent.js';
13
+ import { ApplyDiffHandler } from './handlers/applyDiff.js';
14
+ import { SearchAndReplaceHandler } from './handlers/searchAndReplace.js';
15
+ import { FileUtils } from './utils/fileUtils.js';
16
+
17
+ /**
18
+ * Main class for FileEditor MCP server
19
+ */
20
+ export class FileEditorMCPServer {
21
+ constructor() {
22
+ this.server = new Server(
23
+ {
24
+ name: "fileditor-mcp",
25
+ version: "1.0.0",
26
+ },
27
+ {
28
+ capabilities: {
29
+ tools: {},
30
+ },
31
+ }
32
+ );
33
+
34
+ this.setupHandlers();
35
+ }
36
+
37
+ /**
38
+ * Set up request handlers
39
+ */
40
+ setupHandlers() {
41
+ // List available tools
42
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => {
43
+ return {
44
+ tools: toolDefinitions
45
+ };
46
+ });
47
+
48
+ // Handle tool calls
49
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
50
+ try {
51
+ const { name, arguments: args } = request.params;
52
+
53
+ switch (name) {
54
+ case "set_workspace":
55
+ return await SetWorkspaceHandler.handle(args);
56
+ case "read_files":
57
+ return await ReadFileHandler.handle(args);
58
+ case "write_files":
59
+ return await WriteFileHandler.handle(args);
60
+ case "list_files":
61
+ return await ListFilesHandler.handle(args);
62
+ case "insert_contents":
63
+ return await InsertContentHandler.handle(args);
64
+ case "apply_diffs":
65
+ return await ApplyDiffHandler.handle(args);
66
+ case "search_and_replace":
67
+ return await SearchAndReplaceHandler.handle(args);
68
+ default:
69
+ throw new Error(`Unknown tool: ${name}`);
70
+ }
71
+ } catch (error) {
72
+ return FileUtils.createErrorResponse(error.message);
73
+ }
74
+ });
75
+ }
76
+
77
+ /**
78
+ * Start the server
79
+ * @param {Object} transport - Transport object
80
+ */
81
+ async start(transport) {
82
+ await this.server.connect(transport);
83
+ console.error("FileEditor MCP server running on stdio");
84
+ }
85
+ }