Skip to main content
Glama

fileSystem_tool

Perform file system operations including read, write, copy, move, delete, list files, and manage permissions through the ToolBox MCP Server.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
operationYes要执行的文件系统操作 (例如: read, write, copy)
sourcePathYes源文件的绝对路径
targetPathNo目标文件的绝对路径 (用于 copy/move 操作)
contentNo要写入文件的内容 (用于 'write' 操作)
recursiveNo递归地对目录应用操作
overwriteNo在 copy/move 操作中覆盖已存在的文件
showHiddenNo在 list/listDetails 中包含隐藏文件/目录
fileModeNo文件模式(权限),使用八进制格式 (例如, 755)
uidNo用于 chown 操作的用户 ID
gidNo用于 chown 操作的组 ID

Implementation Reference

  • Main execution logic for the fileSystem_tool, handling various file system operations like read, write, copy, move, delete, list, chmod, chown, and getSize with safety checks.
    export default async function(request: any) {
      try {
        const { 
          operation, 
          sourcePath, 
          targetPath, 
          content,
          recursive, 
          overwrite, 
          showHidden, 
          fileMode, 
          uid, 
          gid 
        } = request.params.arguments;
    
        const basePath = process.cwd();
    
        const isSafePath = (userPath: string | undefined) => {
          if (!userPath) return true; // Allow targetPath to be optional
          const resolvedPath = path.resolve(basePath, userPath);
          return resolvedPath.startsWith(basePath);
        };
    
        if (!isSafePath(sourcePath)) {
          throw new Error(`源路径 "${sourcePath}" 超出了允许的操作目录。`);
        }
        if (!isSafePath(targetPath)) {
          throw new Error(`目标路径 "${targetPath}" 超出了允许的操作目录。`);
        }
    
        switch (operation) {
          case "read": {
            const data = await fs.readFile(sourcePath, 'utf-8');
            return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
          }
          case "write": {
            if (content === undefined) {
              throw new Error('执行 "write" 操作必须提供 "content" 参数。');
            }
            await fs.writeFile(sourcePath, content, 'utf-8');
            return { content: [{ type: "text", text: `文件已成功写入到 ${sourcePath}` }] };
          }
          case "copy": {
            if (!targetPath) {
              throw new Error("执行 'copy' 操作必须提供 'targetPath' 参数。");
            }
            await fs.copy(sourcePath, targetPath, { overwrite });
            return { content: [{ type: "text", text: `文件已成功从 ${sourcePath} 复制到 ${targetPath}` }] };
          }
          case "move": {
            if (!targetPath) {
              throw new Error("执行 'move' 操作必须提供 'targetPath' 参数。");
            }
            await fs.move(sourcePath, targetPath, { overwrite });
            return { content: [{ type: "text", text: `文件已成功从 ${sourcePath} 移动到 ${targetPath}` }] };
          }
          case "delete": {
            await fs.remove(sourcePath);
            return { content: [{ type: "text", text: `文件 ${sourcePath} 已被成功删除。` }] };
          }
          case "list": {
            const files = await fs.readdir(sourcePath);
            // TODO: Implement showHidden filter
            return { content: [{ type: "text", text: JSON.stringify(files, null, 2) }] };
          }
          case "listDetails": {
            const files = await fs.readdir(sourcePath);
            const fileDetails = await Promise.all(
              files.map(async (file) => {
                const filePath = path.join(sourcePath, file);
                const stat = await fs.stat(filePath);
                return {
                  name: file,
                  type: stat.isFile() ? "file" : stat.isDirectory() ? "directory" : "unknown",
                  size: stat.size,
                  modified: stat.mtime,
                  permissions: stat.mode.toString(8),
                };
              })
            );
            // TODO: Implement showHidden filter
            return { content: [{ type: "text", text: JSON.stringify(fileDetails, null, 2) }] };
          }
          case "chmod": {
            if (!fileMode) {
              throw new Error("执行 'chmod' 操作必须提供 'fileMode' 参数。");
            }
            await fs.chmod(sourcePath, fileMode);
            return { content: [{ type: "text", text: `文件权限已成功修改为 ${fileMode}` }] };
          }
          case "chown": {
            if (uid === undefined || gid === undefined) {
              throw new Error("执行 'chown' 操作必须同时提供 'uid' 和 'gid' 参数。");
            }
            await fs.chown(sourcePath, uid, gid);
            return { content: [{ type: "text", text: `文件所有者已成功变更为 UID: ${uid}, GID: ${gid}` }] };
          }
          case "getSize": {
            const stat = await fs.stat(sourcePath);
            let totalSize = stat.size;
    
            if (stat.isDirectory() && recursive) {
              // Note: This is a simplified size calculation for the top-level directory.
              const files = await fs.readdir(sourcePath);
              totalSize = (await Promise.all(files.map(async file => {
                const childPath = path.join(sourcePath, file);
                const childStat = await fs.stat(childPath);
                return childStat.size; // Simplified: doesn't recurse into subdirectories
              }))).reduce((a, b) => a + b, stat.size);
            }
            
            return { content: [{ type: "text", text: `路径 ${sourcePath} 的总大小为: ${totalSize} 字节` }] };
          }
          default:
            throw new Error(`不支持的操作: ${operation}`);
        }
      } catch (error) {
        return {
          content: [
            {
              type: "text",
              text: `Error: ${error instanceof Error ? error.message : String(error)}`
            }
          ],
          isError: true
        };
      }
    }
  • Input schema defining the parameters and structure for the fileSystem_tool, including operation types and required fields.
    export const schema = {
      name: "fileSystem_tool",
      description: "一个强大的文件系统工具,用于执行读、写、复制、移动、删除、列表等操作。",
      type: "object",
      properties: {
        operation: {
          type: "string",
          enum: ["read", "write", "copy", "move", "delete", "list", "listDetails", "chmod", "chown", "getSize"],
          description: "要执行的文件系统操作 (例如: read, write, copy)"
        },
        sourcePath: {
          type: "string",
          description: "源文件的绝对路径"
        },
        targetPath: {
          type: "string",
          description: "目标文件的绝对路径 (用于 copy/move 操作)"
        },
        content: {
          type: "string",
          description: "要写入文件的内容 (用于 'write' 操作)"
        },
        recursive: {
          type: "boolean",
          default: false,
          description: "递归地对目录应用操作"
        },
        overwrite: {
          type: "boolean",
          default: false,
          description: "在 copy/move 操作中覆盖已存在的文件"
        },
        showHidden: {
          type: "boolean",
          default: false,
          description: "在 list/listDetails 中包含隐藏文件/目录"
        },
        fileMode: {
          type: "string",
          pattern: "^[0-7]{3,4}$",
          description: "文件模式(权限),使用八进制格式 (例如, 755)"
        },
        uid: {
          type: "number",
          description: "用于 chown 操作的用户 ID"
        },
        gid: {
          type: "number",
          description: "用于 chown 操作的组 ID"
        }
      },
      required: ["operation", "sourcePath"]
    };
  • Dynamic registration loop that imports the fileSystem_tool module (based on filename) from the tools directory, extracts handler, schema, and destroy functions, and registers them in the global tools list and handlers map.
      const { default: tool, schema, destroy } = await import(importPath);
      const toolName = path.parse(toolPath).name;
    
      // 注册工具
      tools.push({
        name: toolName,
        description: tool.description,
        inputSchema: schema,
        destroy: destroy
      });
    
      // 注册处理函数
      handlers[toolName] = async (request: ToolRequest) => { return await tool(request); };
    } catch (error) {

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/xiaoguomeiyitian/ToolBox'

If you have feedback or need assistance with the MCP directory API, please join our Discord server