虔诚的


*Devin克隆MCP服务器*
用Erlang编写的模型上下文协议(MCP)服务器,为软件项目提供文件、目录和版本控制操作。
特性
🛠️ 文件操作
- 新建目录:使用自动父级创建创建目录
- 新dirs:创建具有多个子项的目录结构
- 移动:安全地移动/重命名文件和目录
- 写:创建/写入支持追加模式的文件
- 读:读取有大小限制的文件内容
- 列出文件:列出包含文件类型和大小的目录内容
- 显示cwd:显示当前工作目录
- 更改cwd:导航到相对目录
🐙 Git操作
- git添加:将文件添加到暂存区(
git add) - git日志:显示提交历史记录(
git log [options]) - 使用 git-diff:显示差异(无参数、1个参数或2个参数)
- git pull:用重基拉动(`git pull
--rebase`)
- git结账分行:创建并签出新分支(
git checkout -b) - git推送:推到远程(
git push) - git全部提交:提交所有更改(
git commit -a -m) - git提交文件:提交特定文件(
git commit -m) - git克隆:克隆存储库(
git clone) - git状态:显示存储库状态(
git status --porcelain)
🔒 安全功能
- 路径验证:只允许相对路径,阻止目录遍历
- 沙箱:所有操作仅限于基本目录
- 文件大小限制:可配置的最大文件大小
- 扩展过滤:可选文件类型限制
- 安全错误处理:不因错误而披露信息
📚 资源和提示
- devout://status:实时服务状态和配置
- devout://help:全面的工具文档
- 创建项目:智能项目结构生成(Erlang、web、API、库)
建筑
OTP设计
- 应用:
devout_app-标准OTP应用程序回调 - 主管:
devout_sup-管理服务器进程生命周期 - 服务器:
devout_server-与erlmcp协调的主gen_server - 运营:
devout_fs-文件系统操作实现 - 验证:
devout_path_validator-安全和路径验证 - Git操作:
devout_git-Git命令实现 - 入口点:
devout_stdio_main-独立的stdio可执行文件
安全模型
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Claude AI │───▶│ devout_server │───▶│ devout_fs │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│ │ │
│ ▼ ▼
┌──────────────────┐ ┌─────────────────┐
│ erlmcp_stdio │ │ path_validator │
│ (MCP Protocol) │ │ (Security) │
└──────────────────┘ └─────────────────┘
│
▼
┌──────────────────┐ ┌─────────────────┐
│ devout_git │───▶│ erlexec │
└──────────────────┘ │ (Proc. Mgmt.) │
└─────────────────┘
先决条件
- Erlang/OTP 25+
- 钢筋3
- Git (用于依赖关系和Git操作)
快速开始
1.建造
git clone
cd devout
rebar3 get-deps
rebar3 compile2.测试
rebar3 eunit3.配置克劳德桌面
编辑 claude_desktop_config.json:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json 视窗: %APPDATA%\Claude\claude_desktop_config.json Linux: ~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"devout": {
"command": "/Users/oubiwann/lab/erlsci/devout/bin/start.sh",
"args": []
}
}
}4.重新启动克劳德桌面
使用示例
📁 目录操作
User: Create a new project structure called "my_app" with src, test, and docs directories
Claude: I'll create that project structure for you.
[Uses new-dirs tool: {"path": "my_app", "children": ["src", "test", "docs"]}]
Directory structure created successfully:
- my_app
- src
- test
- docs🔍 目录探索
User: What files are in the current directory?
Claude: I'll show you the files in the current directory.
[Uses list-files tool: {}]
Contents of .:
[FILE] .DS_Store (6148 bytes)
[DIR] .git
[DIR] .github
[FILE] .gitignore (164 bytes)
[FILE] LICENSE (11358 bytes)
[FILE] Makefile (4612 bytes)
[FILE] README.md (9895 bytes)
[DIR] _build
[DIR] bin
[DIR] config
[DIR] src
[DIR] test📝 文件操作
User: Create a configuration file with some JSON content
Claude: I'll create a config file for you.
[Uses write tool: {"path": "my_app/config.json", "content": "{\n \"port\": 3000,\n \"debug\": true\n}"}]
Content written to file successfully: my_app/config.json (32 bytes)🔍 导航与阅读
User: Show me the current directory and then read the config file
Claude: I'll show the current directory and read the config file.
[Uses show-cwd tool: {}]
Current working directory: /Users/developer/projects
[Uses read tool: {"path": "my_app/config.json"}]
Content of my_app/config.json (32 bytes):
{
"port": 3000,
"debug": true
}🏗️ 项目生成
User: Use the create_project prompt for an Erlang application
Claude: I'll generate an Erlang project structure prompt.
[Uses create_project prompt: {"project_name": "my_erlang_app", "project_type": "erlang"}]
Create a project structure for 'my_erlang_app' (erlang project). Create an Erlang/OTP project structure with directories: src, include, test, priv, rebar.config. Use the devout tools to create the necessary directories and files.🐙 Git操作
查看Git历史记录
User: Show me the last 5 commits
Claude: I'll show you the recent commit history.
[Uses git-log tool: {"args": "--oneline -5"}]
Git log:
a1b2c3d Add new feature
e4f5g6h Fix bug in parser
i7j8k9l Update documentation
m1n2o3p Initial commit创建特征分支
User: Create a new feature branch called "user-authentication"
Claude: I'll create and checkout a new branch for you.
[Uses git-checkout-branch tool: {"branch": "user-authentication"}]
Git checkout branch successful:
Switched to a new branch 'user-authentication'提交更改
User: Add these files to git and commit them with message "Add user auth"
Claude: I'll stage and commit those files for you.
[Uses git-add tool: {"files": ["src/auth.erl", "test/auth_test.erl"]}]
[Uses git-commit-files tool: {"files": ["src/auth.erl", "test/auth_test.erl"], "message": "Add user auth"}]
Git operations successful!与远程同步
User: Pull latest changes from origin main and then push my branch
Claude: I'll sync with the remote repository for you.
[Uses git-pull tool: {"remote": "origin", "branch": "main"}]
[Uses git-push tool: {"remote": "origin"}]
Git sync completed successfully!配置
编辑 config/sys.config 要自定义行为:
[
{devout, [
{max_file_size, 10485760}, % 10MB limit
{allowed_extensions, all}, % or [>, >]
{enable_recursive_delete, false}, % Safety first
{allowed_operations, [ % Restrict available operations
new_dir, new_dirs, move, write, read, list_files, show_cwd, change_cwd
]}
]},
{erlexec, [
{debug, false}, % Enable for git command debugging
{verbose, false}
]}
].Git命令参考
| MCP工具 | Git命令 | 说明 |
|---|---|---|
git-add | git add | 提交阶段文件 |
git-log | git log [options] | 显示提交历史记录 |
git-diff | git diff [ref1] [ref2] | 显示差异 |
git-pull | `git pull | |
| --rebase` | 拉底 | |
git-checkout-branch | git checkout -b | 创建新分支 |
git-push | git push | 推到远程 |
git-commit-all | git commit -a -m | 提交所有更改 |
git-commit-files | git commit -m | 提交特定文件 |
git-clone | git clone | 克隆存储库 |
git-status | git status --porcelain | 显示回购状态 |
Git工具参数
git添加
{
"files": ["file1.txt", "file2.txt"] // Array of files
// OR
"file": "single_file.txt" // Single file
}git日志
{
"args": "--oneline -10" // Optional: git log arguments
}使用 git-diff
{
// No parameters = working directory vs staged
// OR
"ref": "HEAD~1" // Compare against reference
// OR
"ref1": "HEAD~2", // Compare two references
"ref2": "HEAD~1"
}git pull
{
"remote": "origin", // Required: remote name
"branch": "main" // Required: branch name
}git推送
{
"remote": "origin" // Required: remote name
}安全功能
🛡️ 路径安全
- 仅相对路径:拒绝绝对路径(
/etc/passwd❌) - 横向预防:父目录访问被阻止(
../../../etc❌) - 基本目录强制:仅限于工作目录的操作
- 路径规范化:手柄
./,//,以及其他边缘情况
📏 资源限制
- 文件大小限制:可配置的最大文件大小(默认值:10MB)
- 白名单行动:限制每次部署的可用操作
- 扩展过滤:可选文件类型限制
- 内存保护:大文件流式传输
🔒 错误处理
- 信息隐藏:错误不会泄露系统详细信息
- 故障弱化:部分故障处理得很干净
- 审计日志:记录所有操作以供安全审查
- 输入消毒:所有输入在处理前都经过验证
发展
运行测试
# Full test suite
rebar3 eunit
# Specific test modules
rebar3 eunit --module=devout_test
# With coverage
rebar3 cover代码质量
# Static analysis
rebar3 dialyzer
# Cross references
rebar3 xref
# Linting
rebar3 lint开发模式
# Interactive shell
rebar3 shell
# Start stdio server manually
devout_server:start_stdio().添加FS操作
- 添加到允许的操作 在……里面
devout.app.src
- 在devout_fs.erl中实现 (如果需要):
my_operation(Path) ->
case devout_path_validator:validate_path(Path) of
{ok, ValidPath} ->
% Your operation here
ok;
{error, Reason} ->
{error, Reason}
end.- 在devout_app.erl中注册工具:
ok = erlmcp_stdio:add_tool(
>,
>,
fun devout_server:handle_my_operation/1,
SchemaMap
).- 在devout_server.erl中添加处理程序:
handle_my_operation(#{> := Path}) ->
case devout_fs:my_operation(Path) of
ok -> >;
{error, Reason} -> devout_fmt:err(Reason)
end.添加新的Git操作
- 向devout_git.erl添加函数:
my_git_operation(Args) ->
execute_git(["my-operation"] ++ Args).- 添加MCP处理程序:
handle_my_git_operation(#{> := Value}) ->
case my_git_operation([binary_to_list(Value)]) of
{ok, Output} -> >;
{error, Reason} -> devout_fmt:err(Reason)
end.- 在devout_server.erl中注册工具:
ok = erlmcp_stdio:add_tool(
>,
>,
fun devout_git:handle_my_git_operation/1,
Schema
).- 在devout_git_test.erl中添加测试
监控与调试
健康检查
# Check if application is running
erl -eval "io:format('~p~n', [application:which_applications()]), halt()."
# Verify processes
erl -eval "io:format('~p~n', [whereis(devout_server)]), halt()."日志记录
日志转到stderr以避免干扰stdout上的MCP协议:
- 信息:服务生命周期事件
- 警告:违反安全规定,路径无效
- 错误:操作失败、系统错误
故障排除
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 服务未启动 | 缺少依赖项 | rebar3 get-deps && rebar3 compile |
| 路径被拒绝 | 绝对/遍历路径 | 仅使用相对路径 |
| 文件太大 | 超过大小限制 | 检查 max_file_size config |
| 权限被拒绝 | 文件系统权限 | 检查目录所有权 |
| 找不到工具 | 版本不匹配 | 验证erlmcp兼容性 |
| Git命令超时 | 长时间运行的操作 | 增加erlexec配置中的超时 |
| 找不到Git | 缺少Git安装 | 安装Git并确保它在PATH中 |
| 合并冲突 | 冲突更改 | 手动解决冲突 |
| 找不到存储库 | 不在git存储库中 | 使用初始化 git init 首先 |
演出
- 内存使用:~10MB基本+文件缓冲区
- 吞吐量:小文件每秒1000+次操作
- 延迟:典型操作\<10ms
- 可扩展性:单线程,适合交互式使用
贡献
- 分叉存储库
- 创建要素分支
- 添加新功能的测试
- 确保所有测试通过:
rebar3 eunit - 运行静态分析:
rebar3 dialyzer - 提交拉取请求
代码的风格
- 使用OTP原则和gen_server模式
- 正确类型的全面错误处理
- 安全第一设计-验证所有输入
- 用edoc记录所有公共职能
- 遵循Erlang命名约定
致谢
- 建立在卓越之上 erlmcp 图书馆
- 受到Erlang/OTP生态系统安全实践的启发
- 感谢Claude Desktop团队制定MCP协议规范
许可证
Apache许可证2.0-有关详细信息,请参阅许可证文件。
