适用于Scenic GUI应用程序的模型上下文协议(MCP)服务器
版本:1.0.0
使AI助手能够通过键盘输入、鼠标控制和视觉反馈与Scenic GUI应用程序进行交互。非常适合自动化测试、AI驱动的开发工作流程以及辅助工具。
mix.exs中添加请注意,这尚未发布到hex,因此您需要克隆它并将其作为本地依赖项添加。
defp deps do
[
{:scenic_mcp, "../scenic_mcp"}
]
end
Scenic MCP需要命名的视口和驱动程序进程。更新您的监督树:
# 在您的application.ex中
def start(_type, _args) do
children = [
{Scenic, scenic_viewport_config()}
]
Supervisor.start_link(children, strategy: :one_for_one)
end
defp scenic_viewport_config do
[
name: :main_viewport, # 必需!
size: {800, 600},
default_scene: MyApp.RootScene,
drivers: [
[
name: :scenic_driver, # 必需!
module: Scenic.Driver.Local,
window: [title: "我的应用"],
on_close: :stop_system
]
]
]
end
请注意,这里的name定义了将成为视口和驱动程序进程注册名称的原子。我们需要知道这一点以便找到该进程的pid,从而与视口进行交互。我们的解决方案是查找这个特定名称main_viewport,因此您需要在配置中设置此名称以使ScenicMCP正常工作。
视口名称::main_viewport
驱动程序名称::scenic_driver
可选:自定义进程名称
如果您需要不同的进程名称,请进行配置:
# config/config.exs
config :scenic_mcp,
viewport_name: :my_custom_viewport,
driver_name: :my_custom_driver,
port: 9999
cd scenic_mcp
npm install
npm run build
claude mcp add scenic-mcp /path/to/scenic_mcp/dist/index.js
claude mcp list # 验证安装
编辑~/.claude.json:
{
"projects": {
"/path/to/your/project": {
"mcpServers": {
"scenic-mcp": {
"type": "stdio",
"command": "/path/to/scenic_mcp/dist/index.js",
"args": [],
"env": {}
}
}
}
}
}
可选:Tidewave MCP配置
Tidewave为Elixir/Phoenix应用提供运行时检查(日志、SQL查询、代码评估、文档)。如果您的项目包含Tidewave(Flamelex/Quillex),请将以下内容添加到同一项目配置中:
{
"projects": {
"/path/to/your/project": {
"mcpServers": {
"scenic-mcp": {
"type": "stdio",
"command": "/path/to/scenic_mcp/dist/index.js",
"args": [],
"env": {}
},
"tidewave": {
"type": "http",
"url": "http://localhost:4000/tidewave/mcp"
}
}
}
}
}
cd your_scenic_app
iex -S mix
您应该看到:
✅ ScenicMCP成功启动在端口9999上
connect_scenic - 建立与正在运行的Scenic应用的连接get_scenic_status - 检查连接状态和服务器信息send_keys - 发送键盘输入(文本、特殊键、修饰符)send_mouse_move - 将光标移动到坐标位置send_mouse_click - 在坐标处点击(左/右/中间按钮)inspect_viewport - 获取视口结构的文本描述take_screenshot - 捕获PNG屏幕截图(路径或base64)send_keys({ text: "Hello, World!" })
send_keys({ key: "enter" })
send_keys({ key: "escape" })
send_keys({ key: "tab" })
send_keys({ key: "s", modifiers: ["ctrl"] }) // Ctrl+S(保存)
send_keys({ key: "c", modifiers: ["cmd"] }) // Cmd+C(Mac上的复制)
send_keys({ key: "z", modifiers: ["ctrl", "shift"] }) // Ctrl+Shift+Z(重做)
send_mouse_move({ x: 100, y: 200 })
send_mouse_click({ x: 150, y: 250, button: "left" })
send_mouse_click({ x: 300, y: 100, button: "right" }) // 右击
inspect_viewport() // 获取组件结构
take_screenshot({ format: "path" }) // 保存到/tmp
take_screenshot({
filename: "app_state.png",
format: "base64" // 获取base64数据
})
AI代理(Claude Desktop/Code)
↓ stdio
TypeScript MCP服务器(此包)
↓ TCP(端口9999)
Elixir GenServer(ScenicMcp.Server)
↓ 函数调用
Scenic驱动程序进程
↓ 输入事件
您的Scenic应用
# config/config.exs
config :scenic_mcp,
# MCP服务器的TCP端口(默认:9999)
port: 9999,
# 视口进程名称(默认::main_viewport)
viewport_name: :main_viewport,
# 驱动程序进程名称(默认::scenic_driver)
driver_name: :scenic_driver,
# 日志的应用名称(默认:"未知")
app_name: "我的应用"
如果您正在运行多个Scenic应用,请配置独特的端口:
# 在flamelex/config/config.exs中
config :scenic_mcp, port: 9999, app_name: "Flamelex"
# 在quillex/config/config.exs中
config :scenic_mcp, port: 9997, app_name: "Quillex"
# 在your_test/config/test.exs中
config :scenic_mcp, port: 9996, app_name: "测试"
连接到特定端口:
connect_scenic({ port: 9997 }) // 连接到Quillex
npm run build # 一次性构建
npm run dev # 开发模式下的监视模式
npm run bundle # 将dist/*复制到priv/mcp_server/
# Elixir测试
mix test
# 测试特定文件
mix test test/scenic_mcp/server_test.exs
scenic_mcp/
├── lib/
│ ├── scenic_mcp.ex # 模块文档
│ └── scenic_mcp/
│ ├── application.ex # OTP应用
│ ├── config.ex # 配置管理
│ ├── server.ex # TCP服务器(GenServer)
│ └── tools.ex # 工具处理器
├── src/
│ ├── index.ts # MCP服务器入口点
│ ├── connection.ts # TCP连接管理
│ └── tools.ts # 工具定义
├── test/
│ └── scenic_mcp/
│ └── server_test.exs # 集成测试
└── dist/ # 编译的TypeScript
错误: MCP服务器无法连接或工具在Claude Code/Desktop中不可用
解决方法: 编译的dist/index.js文件必须可执行。TypeScript编译不会保留可执行权限,即使源文件具有这些权限也是如此。
修复:
chmod +x /path/to/scenic_mcp/dist/index.js
自动修复: 构建脚本现在会自动使文件可执行。如果您在添加此修复之前进行了构建,则可以:
npm run build(推荐)chmod +x dist/index.js修复后,重新启动Claude Code或开始新的对话以使更改生效。
错误: 端口9999已被使用!
解决方法: 在您的config.exs中配置不同的端口:
config :scenic_mcp, port: 9998
错误: 无法找到Scenic视口进程':main_viewport'
解决方法:
name: :main_viewport在您的Scenic配置中config :scenic_mcp, viewport_name: :your_nameProcess.whereis(:main_viewport)错误: 无法找到Scenic驱动程序进程':scenic_driver'
解决方法:
name: :scenic_driver在您的驱动程序配置中config :scenic_mcp, driver_name: :your_nameProcess.whereis(:scenic_driver)错误: 命令超时5000ms
解决方法:
connect_scenic({ port: YOUR_PORT })如果测试因连接错误而失败:
mix test --trace运行测试以获取详细输出scenic_driver_local依赖项是否正确编译⚠️ 重要安全提示:
localhost - 不对外部网络访问详见SECURITY.md中的详细安全指南。
详见docs/INTEGRATION.md中的逐步集成说明,包括:
所有工具函数返回一致的错误结构:
{
"error": "带有上下文和潜在解决方案的描述性错误消息"
}
成功响应包括一个status字段:
{
"status": "ok",
"message": "操作成功完成",
...附加数据...
}
欢迎贡献!请:
mix test通过MIT许可证 - 详情见LICENSE
详见CHANGELOG.md中的版本历史。
为Elixir和Scenic社区制作,充满爱心