Skip to main content

Restricted file-operation workspace for AI agents (Python bindings over the Rust core)

Project description

Agent Workspace (ws)

基于 Rust 的受限文件操作 CLI,供 Agent 在指定工作目录内安全地读写文件。所有路径均相对于配置的工作区解析,无法越界访问宿主机其他路径。

特性

  • 双后端:本地文件(file)或 MySQL(mysql),通过 config.yaml 切换
  • 路径隔离(file 后端):读写操作限制在 workspace_dir 内,含符号链接逃逸检测
  • 元数据:file 后端使用 *.meta.yaml sidecar;mysql 后端将元数据存入数据库
  • 并发安全:file 后端使用 advisory 文件锁;mysql 后端使用 InnoDB 行锁
  • 按行操作:支持按行区间读取或局部替换写入
  • 本地 MCP 服务ws mcp 通过 stdio 暴露 JSON-RPC(MCP 协议)工具,供 MCP 客户端调用工作区读写列删操作

安装

需要 Rust 工具链。

# 克隆或进入项目目录后
cd rust && cargo build --release

# 安装到 ~/.cargo/bin
cargo install --path rust

构建产物位于 rust/target/release/ws。安装后可直接在终端运行 ws

初始化

使用 init 命令创建新的工作区(生成 config.yaml,file 后端还会创建 data/ 目录):

# 在当前目录初始化(默认 file 后端)
ws init

# 在指定目录初始化(不存在则自动创建)
ws init ./my-agent-workspace
ws init /path/to/workspace

# 使用 MySQL 后端(生成 mysql 配置模板并自动建库建表)
ws init --backend mysql
ws init ./my-agent-workspace --backend mysql

--backend mysql 会写入 MySQL 连接配置模板,并尝试连接数据库、创建库(若不存在)及 workspace_files 表。请编辑 config.yaml 中的 hostuserpassworddatabase 后再使用其他命令。

初始化完成后,进入该目录即可使用其他命令。若目录下已存在 config.yaml,会报错以避免覆盖。

配置

破坏性变更:旧版顶层 workspace_dir / metadata_suffix 已移除。请改用 backend 块,见下方示例。

在项目根目录(或任意启动目录)放置 config.yaml

File 后端(默认)

backend:
  type: file
  workspace_dir: ./data         # 相对 config 文件所在目录解析
  metadata_suffix: ".meta.yaml" # 可省略(默认值)

启动时会校验 workspace_dir 存在且可写。

MySQL 后端

backend:
  type: mysql
  host: localhost
  port: 3306                    # 可省略(默认 3306)
  user: ws_user
  password: change_me
  database: agent_workspace

连接时会自动确保数据库和 workspace_files 表存在。元数据(创建者、描述、时间戳、SHA256)与文件内容存储在同一张表中,不再使用 sidecar 文件。

加载顺序

init 外,其余命令均通过配置文件加载后端。可按以下优先级指定配置文件:

  1. 命令行 --config /path/to/config.yaml
  2. 环境变量 AGENT_WORKSPACE_CONFIG
  3. 当前工作目录下的 config.yaml

init 会生成新的 config.yaml,不使用上述加载逻辑;传入的 --config 对其无效。

路径规则

所有命令的路径参数均为工作区相对路径,例如 docs/foo.txt

路径会按 POSIX 语义归一化,且不能逃出工作区根目录:

输入 归一化结果
docs/foo.txt docs/foo.txt
/docs/foo.txt docs/foo.txt
../docs/foo.txt docs/foo.txt
foo/../bar bar
../etc/passwd etc/passwd(访问的是工作区内的 etc/passwd,不是系统 /etc/passwd

元数据文件(如 foo.txt.meta.yaml)在 read / remove 中视为不存在,不会泄露其内容。

命令

所有需加载配置的命令均支持全局 --config 选项,例如:

ws --config /path/to/config.yaml read docs/foo.txt
ws read docs/foo.txt --config /path/to/config.yaml

两种写法等价;未指定时按上文「加载顺序」解析。

init — 初始化工作区

ws init
ws init ./my-agent-workspace
ws init --backend mysql
ws init ./my-agent-workspace --backend mysql
参数 说明
[path] 可选,目标目录;省略则在当前工作目录初始化
--backend 后端类型:file(默认)或 mysql

read — 读取文件

ws read docs/foo.txt
ws read docs/foo.txt --human
ws read docs/foo.txt --ranges 1-10,20-30
选项 说明
--human 首行输出路径,每行前加行号(如 12 | content
--ranges 1-indexed 行区间,逗号分隔;human 模式下仍显示真实行号

默认输出文件原文(raw)。

write — 写入文件

--content--created-by--desc 均为必选参数:

ws write docs/foo.txt --content "hello\n" --created-by agent-x --desc "需求草稿"

按行区间局部替换(删除 START..END 行,在该位置插入新内容):

ws write docs/foo.txt --ranges 2-5 --content "替换内容\n" --created-by agent-x --desc "局部更新"
选项 说明
--content 写入内容(必选)
--created-by 写入元数据,首次创建时记录(必选)
--desc 文件描述(必选)
--ranges START-END 1-indexed,含端点;省略则整文件覆盖

更新已有文件时,元数据中的 created_by / created_at 会保留,其余字段更新。

list — 列出文件

ws list                  # 列出工作区全部文件
ws list docs             # 只列出 docs/ 下文件
ws list --json
ws list docs --json

默认输出人类可读表格;--json 输出结构化 JSON(含 scopefile_counttotal_size_bytesfiles)。

remove — 删除文件

ws remove docs/foo.txt

同时删除数据文件及对应元数据 sidecar。

mcp — 本地 MCP 服务

Model Context Protocol 服务运行,通过 stdio 收发换行分隔的 JSON-RPC 2.0 消息。MCP 客户端将 ws mcp 作为子进程启动后,即可调用工作区工具。

ws mcp
ws mcp --config /path/to/config.yaml

进程读取 stdin 直到 EOF,所有协议输出写入 stdout(因此该模式下命令本身不向 stdout 打印其他内容)。后端与作用域规则由配置文件决定。

支持的方法:initializetools/listtools/callping,以及忽略的 notifications/*

暴露的工具(每次调用可选 user_id / session_id 进行作用域隔离):

工具 必选参数 可选参数 说明
read path ranges 读取文件,可按 1-indexed 行区间过滤
write pathcontentcreated_bydesc ranges(单个 START-END 写入或局部替换
list path 列出文件,返回 JSON 报告
remove path 删除文件及元数据

工具执行失败(如路径越界、未找到)按 MCP 约定返回 isError: true 的结果而非 JSON-RPC 协议错误;仅调用格式本身非法(缺少工具名、未知工具)才返回协议错误。

示例(手动喂入请求):

printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05"}}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
  '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"write","arguments":{"path":"a.txt","content":"hello\n","created_by":"agent","desc":"demo"}}}' \
  | ws mcp

在 MCP 客户端中的典型配置(以可执行路径启动):

{
  "mcpServers": {
    "agent-workspace": {
      "command": "/path/to/ws",
      "args": ["mcp", "--config", "/path/to/config.yaml"]
    }
  }
}

也可通过环境变量 AGENT_WORKSPACE_CONFIG 指定配置(省略 --config 时生效):

{
  "mcpServers": {
    "agent-workspace": {
      "command": "/path/to/ws",
      "args": ["mcp"],
      "env": { "AGENT_WORKSPACE_CONFIG": "/path/to/config.yaml" }
    }
  }
}

启动目录、--configAGENT_WORKSPACE_CONFIG 需指向有效的 config.yaml,否则服务无法加载后端。

元数据

每个数据文件对应一个 sidecar,命名规则:foo.txtfoo.txt.meta.yaml

示例:

relative_path: docs/foo.txt
created_by: agent-x
desc: 需求文档草稿
created_at: 2026-06-13T13:00:00+08:00
updated_at: 2026-06-13T13:35:00+08:00
size_bytes: 1024
sha256: "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"

退出码

含义
0 成功
1 一般错误
2 路径非法 / 越界
3 未找到(含元数据保护触发)
4 锁冲突

错误信息输出到 stderr。

并发说明

File 后端

文件锁为进程级 advisory lock,仅对同样使用本工具的进程有效。同一文件的并发 write 会串行化;write 在独占锁下同时更新数据文件和元数据 sidecar,保证一致性。

MySQL 后端

write / remove 在事务内对目标行执行 SELECT ... FOR UPDATE,依赖 InnoDB 行锁串行化并发写入。锁等待超时或死锁时返回退出码 4LockConflict),与 file 后端的锁冲突行为一致。read 为普通 SELECT,不加行锁。

开发

cd rust
cargo test          # 单元测试 + 集成测试(不含需 MySQL 的 ignored 测试)
cargo run -- list   # 开发模式运行

Python 绑定(在 python/ 目录):

cd python
uv sync
uv run maturin develop

项目结构

仓库按语言拆分,Rust 核心与 Python 绑定分目录维护:

rust/               Rust crate(CLI、库、MCP、PyO3 绑定)
├── src/
│   ├── main.rs       仅 fn main(),调用 cli::run()
│   ├── lib.rs        模块声明
│   ├── error.rs      错误类型与退出码
│   ├── lock.rs       file 后端的 advisory 文件锁
│   ├── cli.rs        Cli/Commands 定义、命令分发、按作用域打开后端
│   ├── scoping.rs    SessionScope(user/session 作用域解析)
│   ├── ranges.rs     行区间解析、写入替换、过滤
│   ├── metadata.rs   FileMetadata、sidecar 读写、SHA256/时间戳
│   ├── paths/        路径领域
│   │   ├── normalize.rs     工作区相对路径归一化
│   │   ├── resolve.rs       路径解析与越界校验
│   │   ├── metadata_name.rs sidecar 命名与识别
│   │   └── scope_prefix.rs  list 作用域前缀匹配
│   ├── config/       配置领域
│   │   ├── mod.rs       Config / BackendConfig
│   │   ├── raw.rs       反序列化 DTO 与默认值
│   │   ├── load.rs      配置发现、加载、校验
│   │   └── templates.rs init 写出的配置模板
│   ├── storage/      存储领域
│   │   ├── mod.rs       WorkspaceBackend trait + ListReport
│   │   ├── handle.rs    BackendHandle 枚举与工厂
│   │   ├── file.rs      file 后端
│   │   ├── scoped.rs    带作用域的 mysql 后端包装
│   │   └── mysql/       mysql 后端(connection 连接层 + mod CRUD 实现)
│   ├── mcp/          本地 MCP 服务
│   │   ├── mod.rs       模块入口
│   │   ├── protocol.rs  JSON-RPC 2.0 消息类型与错误码
│   │   ├── server.rs    stdio 同步循环与方法分发
│   │   └── tools.rs     工具定义与执行(映射到 WorkspaceBackend)
│   └── commands/     各子命令实现(init/read/write/list/remove)
└── tests/            集成测试

python/             Python 包与构建配置
├── pyproject.toml     maturin/uv(`manifest-path` → ../rust/)
├── uv.lock            uv 依赖锁(可选)
└── agent_workspace/
    ├── __init__.py      公开 API 重导出
    └── py.typed         PEP 561 类型标记

MySQL 集成测试(可选)

需要本地或 CI 中可访问的 MySQL 实例。设置 MYSQL_TEST_URL 后运行 ignored 测试:

export MYSQL_TEST_URL='mysql://user:pass@localhost:3306/agent_workspace_test'
cd rust && cargo test --test mysql_integration -- --ignored

未设置 MYSQL_TEST_URL 时,cargo test 会跳过这些测试,不影响常规 CI。

快速上手

# 新建工作区
ws init ./my-workspace
cd my-workspace

# 写入、读取、列出、删除
ws write docs/readme.md --content "# 标题\n" --created-by me --desc "示例文件"
ws read docs/readme.md --human
ws list
ws remove docs/readme.md

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agent_workspace-2026.6.15a9.tar.gz (57.4 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

agent_workspace-2026.6.15a9-cp39-abi3-win_amd64.whl (1.0 MB view details)

Uploaded CPython 3.9+Windows x86-64

agent_workspace-2026.6.15a9-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ x86-64

agent_workspace-2026.6.15a9-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.3 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ ARM64

agent_workspace-2026.6.15a9-cp39-abi3-macosx_11_0_arm64.whl (1.1 MB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

agent_workspace-2026.6.15a9-cp39-abi3-macosx_10_12_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.9+macOS 10.12+ x86-64

File details

Details for the file agent_workspace-2026.6.15a9.tar.gz.

File metadata

  • Download URL: agent_workspace-2026.6.15a9.tar.gz
  • Upload date:
  • Size: 57.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for agent_workspace-2026.6.15a9.tar.gz
Algorithm Hash digest
SHA256 43e133c6e2a6a4db378627099bd585c3c95faed697a1339d88b1ad502a6d3482
MD5 cc13a24981130dac3928ed274557e211
BLAKE2b-256 16b2007c3bd2e517b914d338becd1a0a401d83d09a04310491a6b5f6b2c8f594

See more details on using hashes here.

File details

Details for the file agent_workspace-2026.6.15a9-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: agent_workspace-2026.6.15a9-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 1.0 MB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for agent_workspace-2026.6.15a9-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 5f0616fa8d0e1eb4fa4b77c30e55ea17e15839e1c2b4ba6c8c39b6ce7a50bcc7
MD5 adcf0bc31ca10d7da33fb0a2ecec07b7
BLAKE2b-256 4527bf576a2e9350cca5e5ed03429e7cc30910ec6faf84531bd07867e041ad1c

See more details on using hashes here.

File details

Details for the file agent_workspace-2026.6.15a9-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

  • Download URL: agent_workspace-2026.6.15a9-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
  • Upload date:
  • Size: 1.3 MB
  • Tags: CPython 3.9+, manylinux: glibc 2.17+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for agent_workspace-2026.6.15a9-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 81f9ea183b80aadd21258ba6f9bb02197df3bb5c07062327361636fd713d8046
MD5 3240f9974a4f1b5bd0a22927282e1a75
BLAKE2b-256 9ad0505527ad57f6ab693583f53b03bbd31cf6c23f53b41a8b79414c6dec0c94

See more details on using hashes here.

File details

Details for the file agent_workspace-2026.6.15a9-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

  • Download URL: agent_workspace-2026.6.15a9-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
  • Upload date:
  • Size: 1.3 MB
  • Tags: CPython 3.9+, manylinux: glibc 2.17+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for agent_workspace-2026.6.15a9-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 58e29646e0131e019b52c5e6cdf2e2dedb71624053a859dd36bb66393595f0b1
MD5 5754cbf2857f966a0a7c95b84aed3028
BLAKE2b-256 e4bf2625b85b20db58f4ab91381a205b780ba6d200ec720c24e15cc48a6ee3e4

See more details on using hashes here.

File details

Details for the file agent_workspace-2026.6.15a9-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

  • Download URL: agent_workspace-2026.6.15a9-cp39-abi3-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.9+, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for agent_workspace-2026.6.15a9-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8b24047cd534efe6dff3ce556287f1bb1a5263f430164152a2c5741f1cf66750
MD5 0e4fed5d09894792fdb2eedfca96cf27
BLAKE2b-256 434a61c075ae974cd9996dd72af135631008edc34a4a4099244039beafdc92fa

See more details on using hashes here.

File details

Details for the file agent_workspace-2026.6.15a9-cp39-abi3-macosx_10_12_x86_64.whl.

File metadata

  • Download URL: agent_workspace-2026.6.15a9-cp39-abi3-macosx_10_12_x86_64.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.9+, macOS 10.12+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for agent_workspace-2026.6.15a9-cp39-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 c24ba17447416a746860aa6cdb66eb1597edc650c0d40546152a1f8a1236ff35
MD5 5b75d68f774bd654dc563ead19870ec0
BLAKE2b-256 0676b684ccaa995cdbe08d77d996b5db4f220fdbacec70d10eddf1e0a9b8f6c6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page