@gabrielmaialva33/mcp-filesystem
Version:
MCP server for secure filesystem access
118 lines • 4.49 kB
JavaScript
import { zodToJsonSchema } from 'zod-to-json-schema';
import { BashExecuteArgsSchema, BashPipeArgsSchema, bashExecute, bashPipe, } from '../../utils/bash/bash_tools.js';
import { metrics } from '../../metrics/index.js';
import { logger } from '../../logger/index.js';
import { FileSystemError } from '../../errors/index.js';
export function getBashToolsSchema() {
return [
{
name: 'bash_execute',
description: 'Execute a Bash command directly with output capture. ' +
'More flexible than execute_command but still with security restrictions. ' +
'Allows for direct access to Bash functionality.',
inputSchema: zodToJsonSchema(BashExecuteArgsSchema),
},
{
name: 'bash_pipe',
description: 'Execute a sequence of Bash commands piped together. ' +
'Allows for powerful command combinations with pipes. ' +
'Results include both stdout and stderr.',
inputSchema: zodToJsonSchema(BashPipeArgsSchema),
},
];
}
export async function handleBashExecute(args, config) {
const endMetric = metrics.startOperation('bash_execute');
try {
const parsed = BashExecuteArgsSchema.safeParse(args);
if (!parsed.success) {
throw new FileSystemError(`Invalid arguments for bash_execute`, 'INVALID_ARGS', undefined, {
errors: parsed.error.format(),
});
}
const result = await bashExecute(parsed.data, config);
const formattedResponse = formatCommandResult(result, parsed.data.command);
await logger.debug(`Bash command executed: ${args.command}`, {
exitCode: result.exitCode,
});
endMetric();
return {
content: [
{
type: 'text',
text: formattedResponse,
},
],
};
}
catch (error) {
metrics.recordError('bash_execute');
if (error instanceof FileSystemError) {
await logger.error(`Error in bash_execute:`, error.toJSON());
return {
content: [{ type: 'text', text: `Error: ${error.message}` }],
isError: true,
};
}
const errorMessage = error instanceof Error ? error.message : String(error);
await logger.error(`Unexpected error in bash_execute:`, { error });
return {
content: [{ type: 'text', text: `Error: ${errorMessage}` }],
isError: true,
};
}
}
export async function handleBashPipe(args, config) {
const endMetric = metrics.startOperation('bash_pipe');
try {
const parsed = BashPipeArgsSchema.safeParse(args);
if (!parsed.success) {
throw new FileSystemError(`Invalid arguments for bash_pipe`, 'INVALID_ARGS', undefined, {
errors: parsed.error.format(),
});
}
const result = await bashPipe(parsed.data, config);
const formattedResponse = formatCommandResult(result, parsed.data.commands.join(' | '));
await logger.debug(`Bash pipe executed`, {
commands: parsed.data.commands,
exitCode: result.exitCode,
});
endMetric();
return {
content: [
{
type: 'text',
text: formattedResponse,
},
],
};
}
catch (error) {
metrics.recordError('bash_pipe');
if (error instanceof FileSystemError) {
await logger.error(`Error in bash_pipe:`, error.toJSON());
return {
content: [{ type: 'text', text: `Error: ${error.message}` }],
isError: true,
};
}
const errorMessage = error instanceof Error ? error.message : String(error);
await logger.error(`Unexpected error in bash_pipe:`, { error });
return {
content: [{ type: 'text', text: `Error: ${errorMessage}` }],
isError: true,
};
}
}
function formatCommandResult(result, command) {
let output = `Command: ${command}\n`;
output += `Exit Code: ${result.exitCode}\n\n`;
if (result.stdout.trim()) {
output += `STDOUT:\n${result.stdout}\n`;
}
if (result.stderr.trim()) {
output += `STDERR:\n${result.stderr}\n`;
}
return output;
}
//# sourceMappingURL=index.js.map