关于 Virtual Filesystem
Virtual Filesystem 是为 AI Agent 提供持久化 PostgreSQL 文件工作区的 MCP 服务。它支持自动隔离会话、跨会话共享命名存储和文件搜索,且不访问主机文件系统。
主要功能
- 01PostgreSQL 持久化文件存储
- 02自动隔离会话
- 03共享命名存储
- 04POSIX 风格文件操作
- 05Glob 与正则内容搜索
- 06可选行级安全策略
适用场景
- 01在工具调用间保留 Agent 临时文件
- 02跨会话保存记忆
- 03在多个 Agent 间共享文件
- 04存储并搜索 CI/CD 构建产物
MCP 相关
通过标准 MCP 工具提供文件操作和搜索,包括 `read`、`write`、`glob` 和 `grep`。MCP 客户端可将其配置为服务端,会话身份由系统自动处理。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y mcp-virtual-fsDATABASE_URL密钥PostgreSQL connection string (e.g. postgresql://user:pass@host:5432/dbname)VFS_AUTO_INITAuto-create database tables on startup (set to 'true' for first run)VFS_SESSION_IDDeterministic session ID for resumable sessions across restartsVFS_ENABLE_RLSEnable PostgreSQL Row Level Security for database-enforced session isolation本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
11收录的工具列表 · 更新于 3 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| path | string | 是 | 文件的绝对路径(例如 /src/index.ts) |
| store | string | 否 | 用于跨会话访问的命名持久化存储。会话是临时的(每个 MCP 连接对应一个会话);命名存储会无限期保留。省略时使用会话自身的命名空间。 |
详细介绍
mcp-virtual-fs
一个 MCP 服务,为 AI Agent 提供由 PostgreSQL 提供支持的持久化虚拟文件系统。支持会话隔离的文件操作、跨会话共享存储、glob/grep 搜索和行级安全性,所有功能均以标准 Model Context Protocol 工具的形式提供。
适用于任何 MCP 客户端:Claude Desktop、Claude Code、Cursor、Windsurf、Cline 等。
功能
- 持久化文件存储 — 文件存储在 PostgreSQL 中,可在进程重启、容器回收和重新部署后保留
- 会话隔离 — 每个 Agent 会话都会自动获得独立命名空间,无需配置
- 跨会话存储 — 命名的持久化存储,可用于在 Agent 之间共享数据或保存 Agent 的长期记忆
- 11 种 POSIX 风格工具 —
read、write、append、stat、ls、mkdir、rm、mv、glob、grep、stores - Glob 和 grep 搜索 — 按模式(
**/*.ts)查找文件,或通过正则表达式搜索内容,由 PostgreSQL 三元组索引提供支持 - 行级安全性 — 可选的数据库强制隔离功能,适用于多租户部署中的会话隔离
- 零配置 — 设置
VFS_AUTO_INIT=true后,首次运行时自动创建表
使用场景
- Agent 草稿区 — 为大模型 Agent 提供持久化工作区,以便在多次工具调用间读写文件
- Agent 长期记忆 — 使用命名存储跨会话保存笔记、上下文和知识
- 多 Agent 协作 — 多个 Agent 通过跨会话存储共享文件
- 沙盒化文件操作 — Agent 与虚拟文件系统交互,而非访问主机操作系统
- CI/CD 构件存储 — 在可查询的文件系统中保存构建输出、日志和报告
原因
Agent 使用文件系统管理上下文效果很好,但如果将存储与 Agent 运行时耦合,Pod 重启或容器回收时数据就会丢失。此 MCP 服务通过将文件操作转移到 PostgreSQL,使存储与运行时解耦,让 Agent 获得持久化、隔离且可搜索的文件存储,同时无需接触主机文件系统。
前提条件
- Node.js 20 或更高版本
- PostgreSQL 14 或更高版本(需安装
pg_trgm扩展;大多数发行版均已包含)
快速开始
1. 设置 PostgreSQL
# Using Docker
docker run -d --name vfs-postgres \
-e POSTGRES_DB=vfs \
-e POSTGRES_PASSWORD=postgres \
-p 5432:5432 \
postgres:16-alpine
2. 配置 MCP 客户端
将以下内容添加到 MCP 客户端配置中(例如 Claude Desktop 的 claude_desktop_config.json 或 Claude Code 的 .mcp.json):
{
"mcpServers": {
"virtual-fs": {
"command": "npx",
"args": ["-y", "mcp-virtual-fs"],
"env": {
"DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/vfs",
"VFS_AUTO_INIT": "true"
}
}
}
}
完成。首次运行时,VFS_AUTO_INIT=true 会创建表。
3. 使用工具
工具名称采用简短的 POSIX 风格:
write({ path: "/notes/todo.md", content: "# My Tasks\n- Ship feature" })
read({ path: "/notes/todo.md" })
ls({ path: "/notes" })
glob({ pattern: "**/*.md" })
grep({ pattern: "TODO" })
所有工具均返回结构化 JSON 响应。
工具
| 工具 | 参数 | 返回值 | 描述 |
|---|---|---|---|
read | path | {content, size} | 读取文件内容 |
write | path、content | {path, size, has_parents} | 写入文件(自动创建父目录) |
append | path、content | {path, appended_bytes} | 追加到文件(文件不存在时会创建) |
stat | path | {exists, type?, size?, children?} | 检查是否存在并获取元数据 |
ls | path | {entries: [{name, type}]} | 列出目录(目录优先,然后按字母顺序排列) |
mkdir | path | {path, already_existed} | 创建目录及其父目录(mkdir -p) |
rm | path | {path, deleted} | 递归删除文件或目录 |
mv | source、destination | {source, destination} | 移动或重命名文件或目录 |
glob | pattern | {files, count} | 按 glob 模式查找文件(例如,**/*.ts、**/*.{js,ts}) |
grep | pattern、path_filter? | {matches, count} | 使用正则表达式搜索文件内容 |
stores | (无) | {stores, count} | 列出所有持久化存储名称 |
除 stores 外,所有工具都接受可选的 store 参数,用于跨会话持久化存储。
会话管理
会话会自动处理——工具参数中无需提供会话 ID。
工作方式:
| 传输方式 | 会话标识 | 行为 |
|---|---|---|
| stdio | 每个进程自动生成的 UUID | 每个 MCP 连接对应一个唯一会话 |
| HTTP/SSE | 由传输方式提供的 sessionId | 由 MCP 协议处理 |
| 任意 | VFS_SESSION_ID 环境变量 | 确定性/可恢复会话 |
优先级:传输方式的 sessionId > VFS_SESSION_ID 环境变量 > 自动生成的 UUID。
可恢复会话
若要在进程重启后恢复之前的会话,请设置一个确定性的会话 ID:
{
"env": {
"DATABASE_URL": "postgresql://...",
"VFS_SESSION_ID": "my-agent-session-1"
}
}
跨会话存储
命名存储会跨会话持久保留。任何会话都可以通过传递 store 参数来读写存储:
// Session A writes to a store
write({ path: "/context.md", content: "project notes", store: "agent-memory" })
// Session B (days later) reads from the same store
read({ path: "/context.md", store: "agent-memory" })
// Without `store`, operations target the session's own namespace
write({ path: "/scratch.txt", content: "session-only data" })
// List all available stores
stores()
存储会在首次使用时自动创建。
环境变量
| 变量 | 必需 | 默认值 | 描述 |
|---|---|---|---|
DATABASE_URL | 是 | — | PostgreSQL 连接字符串 |
VFS_AUTO_INIT | 否 | false | 启动时自动创建表 |
VFS_SESSION_ID | 否 | random UUID | 确定性会话 ID |
VFS_ENABLE_RLS | 否 | false | 启用行级安全性 |
VFS_STORAGE_BACKEND | 否 | postgres | 存储后端类型 |
手动设置数据库
如果你希望自行管理架构,而不使用 VFS_AUTO_INIT:
psql $DATABASE_URL -f sql/schema.sql
行级安全性(可选)
RLS 提供由数据库强制执行的会话隔离。即使应用代码存在遗漏 WHERE session_id = 子句的错误,PostgreSQL 本身也会阻止跨会话访问。
# Run after schema.sql
psql $DATABASE_URL -f sql/rls.sql
# Update the vfs_app password
psql $DATABASE_URL -c "ALTER ROLE vfs_app PASSWORD 'your-secure-password'"
然后将 MCP 服务配置为使用 vfs_app 连接:
{
"env": {
"DATABASE_URL": "postgresql://vfs_app:your-secure-password@localhost:5432/vfs",
"VFS_ENABLE_RLS": "true"
}
}
开发
要求
- Node.js 20+
- Docker(用于集成测试——通过 testcontainers 运行 PostgreSQL)
git clone https://github.com/lu-zhengda/mcp-virtual-fs.git
cd mcp-virtual-fs
npm install
npm run build
命令
| 命令 | 描述 |
|---|---|
npm run build | 编译 TypeScript |
npm test | 运行所有测试(需要 Docker) |
npm run test:unit | 仅运行单元测试 |
npm run test:integration | 仅运行集成测试 |
npm run lint | 运行 ESLint |
npm run lint:fix | 自动修复 lint 问题 |
npm run dev | 使用 tsx 运行(无需构建) |
测试
测试使用 testcontainers 在 Docker 中启动真实的 PostgreSQL 实例。不使用模拟对象——集成测试会执行实际的 SQL 查询、三元组索引和 RLS 策略。
# Requires Docker running
npm test
会话清理
可以定期清理临时会话:
DELETE FROM vfs_sessions
WHERE is_persistent = false
AND created_at < now() - interval '7 days';
vfs_nodes 上的 ON DELETE CASCADE 会自动清理文件。持久化存储(通过 store 参数创建)不会受到影响。
许可证
MIT
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。