System Setup Guide for Remote Local File Manipulation Using Flask and MCP Server

Overview

This project aims to build and validate a remote API service enabling local filesystem operations by integrating MCP Server and Flask. The main functionalities include:

  • Remote execution of operations such as directory listing, file creation, file deletion, and file modification.
  • Providing an HTTP API interface with Flask, powered by MCP Server.

Setup Instructions

1. Install Required Packages

Node.js and MCP Server

MCP Server requires Node.js. Follow these steps to install:

  1. Install the latest LTS version of Node.js from Node.js Official Website.
  2. Install MCP Server globally:
   npm install -g @modelcontextprotocol/server-filesystem

Python and Flask

To build the remote API server with Flask, you’ll need the Python environment:

  1. Download and install Python from Python Official Website.
  2. Install the required libraries:
   pip install flask flask-cors

2. Project Directory Structure

Create the files and directories according to the following structure:

C:\dev\mcp\
│
├── server-filesystem.cmd
├── bridge.js
└── flask_api.py

Code Details

server-filesystem.cmd

A script for launching MCP Server to enable remote filesystem operations:

@echo off
npx -y @modelcontextprotocol/server-filesystem C:\dev\mcp\test

bridge.js

A Node.js script to execute and test MCP Server behaviors (CRUD operations):

const { spawn } = require("child_process");

// 调用 server-filesystem.cmd 启动 MCP Server
const mcpServer = spawn("cmd.exe", ["/c", "C:\\dev\\mcp\\server-filesystem\\server-filesystem.cmd"], {
    env: process.env, // 继承当前环境变量
    shell: true       // 必须启用 shell 模式以运行 .cmd 文件
});

// 监听标准输出,打印 MCP 服务输出日志
mcpServer.stdout.on("data", (data) => {
    console.log(`MCP Server Output: ${data}`);
});

// 监听标准错误(已分类处理)
// 将已知的启动信息归类为 "MCP Server Info",其他则作为真正的错误
mcpServer.stderr.on("data", (data) => {
    const message = data.toString();
    if (message.includes("Secure MCP Filesystem Server")) {
        console.log(`MCP Server Info: ${message}`);
    } else if (message.includes("Allowed directories")) {
        console.log(`MCP Server Info: ${message}`);
    } else {
        console.error(`MCP Server Error: ${message}`);
    }
});

// 捕获 MCP 服务关闭事件
mcpServer.on("close", (code) => {
    console.log(`MCP Server exited with code ${code}`);
});

// === 新增功能:测试 MCP Server 的功能 ===
// 延迟执行功能以确保 MCP Server 已启动完成
setTimeout(() => {
    // 测试 1:列出目录内容
    console.log("Running Directory List Test...");
    const listTest = spawn("cmd.exe", ["/c", "dir C:\\dev\\mcp\\test"], {
        env: process.env,
        shell: true,
    });

    listTest.stdout.on("data", (data) => {
        console.log(`Directory List Output: ${data}`);
    });

    listTest.stderr.on("data", (data) => {
        console.error(`Directory List Error: ${data}`);
    });

    listTest.on("close", () => {
        console.log("Directory List Test Finished.");
    });
}, 3000); // 延迟 3 秒进行目录列表测试

setTimeout(() => {
    // 测试 2:创建新文件
    console.log("Running File Creation Test...");
    const writeTest = spawn("cmd.exe", ["/c", "echo Hello, MCP Server! > C:\\dev\\mcp\\test\\test-write.txt"], {
        env: process.env,
        shell: true,
    });

    writeTest.stdout.on("data", (data) => {
        console.log(`File Creation Output: ${data}`);
    });

    writeTest.stderr.on("data", (data) => {
        console.error(`File Creation Error: ${data}`);
    });

    writeTest.on("close", () => {
        console.log("File Creation Test Finished. Please check the file in 'C:\\dev\\mcp\\test'.");
    });
}, 7000); // 延迟 7 秒执行文件创建测试

// 测试 4:删除刚创建的文件
setTimeout(() => {
    console.log("Running File Deletion Test...");
    const deleteTest = spawn("cmd.exe", ["/c", "del C:\\dev\\mcp\\test\\test-write.txt"], {
        env: process.env,
        shell: true,
    });

    deleteTest.stdout.on("data", (data) => {
        console.log(`File Deletion Output: ${data}`);
    });

    deleteTest.stderr.on("data", (data) => {
        console.error(`File Deletion Error: ${data}`);
    });

    deleteTest.on("close", () => {
        console.log("File Deletion Test Finished. Please check if the file is removed from 'C:\\dev\\mcp\\test'.");
    });
}, 15000); // 延迟 15 秒测试文件删除

flask_api.py

A Flask API server that provides CRUD operations through HTTP requests:

from flask import Flask, request, jsonify, make_response
from flask_cors import CORS
import subprocess
import json  # Use json module for building responses manually

# Initialize Flask app
app = Flask(__name__)

# Enable Cross-Origin Resource Sharing (CORS)
CORS(app)

# Ensure Flask does not escape non-ASCII characters in responses
app.config['JSON_AS_ASCII'] = False


# Utility function: Construct JSON response with UTF-8 encoding
def json_response(data, status=200):
    response = make_response(json.dumps(data, ensure_ascii=False), status)
    response.headers['Content-Type'] = 'application/json; charset=utf-8'
    return response


# Route: List directory contents
@app.route('/list-files', methods=['GET'])
def list_files():
    # Fetch 'dir' parameter from the GET request
    directory = request.args.get('dir')
    if not directory:
        return json_response({"error": "Missing 'dir' parameter"}, 400)

    try:
        # Use subprocess to run the Windows 'dir' command
        result = subprocess.run(
            ["cmd.exe", "/c", f"dir {directory}"],
            stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
        )
        # If the command failed, return the error
        if result.returncode != 0:
            return json_response({"error": result.stderr.strip()}, 500)
        # Return the directory listing as the response
        return json_response({"output": result.stdout.strip()})
    except Exception as e:
        # Catch any unexpected exceptions
        return json_response({"error": str(e)}, 500)


# Route: Create a file with content
@app.route('/create-file', methods=['POST'])
def create_file():
    # Parse the file_path and content from the POST request
    data = request.get_json()
    file_path = data.get('file_path')
    content = data.get('content', '')

    if not file_path:
        return json_response({"error": "Missing 'file_path' parameter"}, 400)

    try:
        # Use subprocess to run the Windows 'echo' command to write to a file
        result = subprocess.run(
            ["cmd.exe", "/c", f"echo {content} > {file_path}"],
            stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
        )
        # If the command failed, return the error
        if result.returncode != 0:
            return json_response({"error": result.stderr.strip()}, 500)
        # Return success message
        return json_response({"message": f"File '{file_path}' created successfully"})
    except Exception as e:
        # Catch any unexpected exceptions
        return json_response({"error": str(e)}, 500)


# Route: Delete a specific file
@app.route('/delete-file', methods=['DELETE'])
def delete_file():
    # Parse the file_path from the DELETE request
    data = request.get_json()
    file_path = data.get('file_path')

    if not file_path:
        return json_response({"error": "Missing 'file_path' parameter"}, 400)

    try:
        # Use subprocess to run the Windows 'del' command to delete the file
        result = subprocess.run(
            ["cmd.exe", "/c", f"del {file_path}"],
            stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
        )
        # If the command failed, return the error
        if result.returncode != 0:
            return json_response({"error": result.stderr.strip()}, 500)
        # Return success message
        return json_response({"message": f"File '{file_path}' deleted successfully"})
    except Exception as e:
        # Catch any unexpected exceptions
        return json_response({"error": str(e)}, 500)


# Route: Read contents of a specific file
@app.route('/read-file', methods=['GET'])
def read_file():
    # Fetch 'file_path' parameter from the GET request
    file_path = request.args.get('file_path')
    if not file_path:
        return json_response({"error": "Missing 'file_path' parameter"}, 400)

    try:
        # Open the file in 'read' mode with UTF-8 encoding
        with open(file_path, 'r', encoding='utf-8') as file:
            content = file.read()
        # Return the file content in the response
        return json_response({"file_path": file_path, "content": content})
    except FileNotFoundError:
        # Return 404 if the file does not exist
        return json_response({"error": f"File '{file_path}' not found."}, 404)
    except Exception as e:
        # Catch any unexpected exceptions
        return json_response({"error": str(e)}, 500)


# Run the Flask app on all available IPs (0.0.0.0) at port 5000
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

Important Notes

  1. Path Formatting:
  • Ensure file paths sent to the Flask API use double backslashes (e.g., C:\\path\\to\\file).
  1. Security:
  • Add additional security layers (e.g., API Keys or access control) as file operations can pose risks.
  1. Production Deployment:
  • Flask’s development server is not suitable for production. Use Gunicorn or uWSGI for deployment.

Using bridge.js (Node.js Script)

To test and interact with the MCP server for file operations, run:

node bridge.js
  • Starts the MCP server.
  • Performs directory listing, file creation, and file deletion tests, with results outputted in the console.

Starting Flask API (flask_api.py)

To host the API server:

  1. Navigate to the project directory.
  2. Run the script:
   python flask_api.py
  1. API will be available at http://0.0.0.0:5000 for HTTP operations.

Testing Results

  1. Sample curl Commands (for Ubuntu):
# check folder
curl "http://yourTargetIP:yourTargetPort/list-files?dir=C:\\dev\\mcp\\test"
 
# create file
curl -X POST -H "Content-Type: application/json" \
-d '{"file_path": "C:\\dev\\mcp\\test\\test.txt", "content": "Created via Flask API"}' \
"http://yourTargetIP:yourTargetPort/create-file"

# read file
curl "http://yourTargetIP:yourTargetPort/read-file?file_path=C:\\dev\\mcp\\test\\test.txt"

# delete file
curl -X DELETE -H "Content-Type: application/json" \
-d '{"file_path": "C:\\dev\\mcp\\test\\test.txt"}' \
"http://yourTargetIP:yourTargetPort/delete-file"


Future Enhancements

  • Enable file upload and download functionality.
  • Introduce authentication mechanisms to RESTful APIs.
  • Add batch operations and file movement capabilities.

留下评论

通过 WordPress.com 设计一个这样的站点
从这里开始