1. 项目缘起:一个远程自动化部署的刚需场景

最近在折腾一个挺有意思的自动化场景:我手头有两台电脑,一台是主力开发机(A机),另一台是刚装好Debian的测试服务器(B机)。我的目标是在B机上部署OpenClaw,让它成为一个AI技能执行节点。最直接的想法当然是手动操作:在B机上打开终端,下载、安装、配置……但转念一想,这过程既重复又耗时,而且如果以后需要批量初始化多台机器呢?手动操作显然不是长久之计。

这时,一个组合方案浮现在脑海: 向日葵远程控制 + OpenClaw的MCP(Model Context Protocol)协议 。向日葵负责建立到B机的远程桌面连接,提供图形化或命令行操作的基础通道;而OpenClaw的MCP则提供了一套标准化的、可编程的接口,理论上可以通过A机上的OpenClaw主控端,向B机发送安装指令。这个想法听起来很美好,但实操起来,坑点不少。比如,如何让A机的OpenClaw“认识”并“指挥”B机?安装脚本如何跨平台、跨网络可靠执行?网络中断了怎么办?权限问题怎么处理?

这个项目,就是要把这个“理论上”变成“实际上”。我们将通过配置OpenClaw的MCP服务器,使其能够接收来自A机的指令,并借助向日葵建立的通道,在B机上自动完成OpenClaw客户端的安装与基础配置。这不仅仅是两个工具的简单拼接,更是一次对自动化运维、跨设备AI技能分发边界的探索。

2. 核心组件拆解:向日葵、OpenClaw与MCP的角色定位

要实现“A机指挥B机装软件”,我们需要清晰地理解每个组件在整个链路中扮演的角色,以及它们之间如何衔接。

2.1 向日葵远程控制:稳定可靠的物理通道

向日葵在这里的核心价值是提供了一个 稳定、低延迟、具备图形化能力的远程访问通道 。虽然我们的最终目标是自动化,但在调试和初始化阶段,图形界面是不可或缺的。例如,首次在B机(假设是Debian桌面版)上安装向日葵客户端时,可能需要图形界面进行扫码登录或输入验证码。更重要的是,向日葵建立了可靠的TCP连接,为后续的自动化脚本执行铺平了道路。

为什么选择向日葵而不是纯SSH? 对于Linux服务器,SSH当然是首选。但考虑到通用性,B机可能是Windows,也可能是带有桌面环境的Linux。向日葵提供了一个统一的远程访问入口,屏蔽了操作系统的差异。此外,在需要通过图形界面确认某些安装步骤(如许可协议)时,向日葵的远程桌面功能是无可替代的。我们的自动化脚本,最终会通过向日葵建立的这个通道,以命令行方式在B机上执行。

2.2 OpenClaw与MCP协议:自动化的大脑与神经

OpenClaw是一个开源的AI智能体(Agent)框架,它本身可以执行各种技能(Skill)。而 MCP(Model Context Protocol) 是本次实战的关键。你可以把MCP理解为OpenClaw的“插件”或“扩展”协议。一个MCP服务器(MCPServer)对外提供一组标准的工具(Tools)或资源(Resources),而OpenClaw(作为MCP客户端)可以调用这些工具。

在本项目中,我们需要在 A机 上运行OpenClaw主程序,并将其配置为MCP客户端。同时,我们需要在 A机 上开发一个自定义的MCP服务器。这个自定义服务器的核心功能是:提供一个名为 install_openclaw_on_remote 的工具。当A机上的OpenClaw(或通过OpenClaw接入的AI,如Claude)被要求“给B机安装OpenClaw”时,它就会调用这个工具。

那么,这个工具具体做什么呢?它会包含一个脚本,这个脚本能通过某种方式(这就是与向日葵结合的地方)在B机上执行安装命令。所以, MCP协议在这里的作用是标准化了“安装OpenClaw”这个指令的接收和触发接口 ,让AI可以通过OpenClaw框架自然地理解和执行这个复杂任务。

2.3 技术链路全景图

整个流程的抽象链路如下:

  1. 准备阶段 :在B机上安装并登录向日葵客户端,确保A机可以通过向日葵远程控制B机。
  2. 开发阶段 :在A机上,编写一个自定义的MCP服务器。该服务器内嵌一个脚本,该脚本能利用向日葵的命令行工具或API,向B机发送命令。
  3. 配置阶段 :在A机上,配置OpenClaw,将我们开发的自定义MCP服务器添加为其可用的MCP服务器之一。
  4. 执行阶段 :用户在A机上通过OpenClaw的界面(或与之对话的AI)发出指令:“在B机上安装OpenClaw”。OpenClaw的MCP客户端会调用我们自定义MCP服务器的 install_openclaw_on_remote 工具。该工具执行内嵌脚本,通过向日葵的通道在B机上运行OpenClaw的安装命令(如 curl | bash docker pull )。
  5. 反馈阶段 :B机上的安装脚本将执行结果(成功、失败及日志)返回给A机上的MCP服务器,MCP服务器再将其结构化地返回给OpenClaw,最终呈现给用户。

可以看到, 向日葵解决了“通道”问题,MCP解决了“指令标准化”问题,而我们的自定义脚本是连接二者的“粘合剂”

3. 实战步骤一:B机环境准备与向日葵部署

万事开头难,第一步是确保B机处于可被远程控制且能执行自动化命令的状态。

3.1 B机系统基础配置

假设B机是一台新安装的Debian 12系统。首先,我们需要进行基础配置,为后续的远程安装打下基础。

# 1. 更新系统包列表
sudo apt update && sudo apt upgrade -y

# 2. 安装必要的基础工具
# curl/wget用于下载,git用于克隆代码(可选),sudo确保有权限
sudo apt install -y curl wget git sudo

# 3. (关键)配置用户权限
# 确保当前用户有sudo权限且无需密码执行特定命令,这对自动化至关重要。
# 编辑sudoers文件需要格外小心,建议使用visudo
sudo visudo

在打开的文件末尾,添加一行(请将 your_username 替换为B机的实际用户名):

your_username ALL=(ALL) NOPASSWD: /usr/bin/apt, /usr/bin/curl, /usr/bin/wget, /bin/bash

这一行的意思是,允许 your_username 用户无需密码使用 apt , curl , wget , bash 命令。这大大简化了自动化脚本的复杂度,避免了交互式密码输入。 注意:此操作存在安全风险,仅建议在受信任的测试环境进行。生产环境应使用更细粒度的权限控制或SSH密钥认证。

3.2 安装并配置向日葵远程控制

向日葵提供了Linux版的命令行安装包,这正适合我们的自动化场景。

# 1. 下载向日葵Linux远程控制软件
# 以Debian/Ubuntu的64位系统为例,从向日葵官网获取最新.deb包链接
wget -O sunlogin.deb https://dl-cdn.oray.com/sunlogin/linux/amd64/sunloginclient_xxx_amd64.deb
# 注意:上面的xxx需要替换为实际版本号,请访问向日葵官网查看最新链接。

# 2. 安装依赖(向日葵客户端可能需要)
sudo apt install -y libwebkit2gtk-4.0-37 libayatana-appindicator3-1

# 3. 安装向日葵客户端
sudo dpkg -i sunlogin.deb
# 如果报告依赖错误,运行以下命令修复
sudo apt --fix-broken install -y

# 4. 启动向日葵服务
sudo systemctl start runsunloginclient.service
sudo systemctl enable runsunloginclient.service

# 5. (重要)获取本机识别码与验证码
# 向日葵通常会在安装后自动生成,可通过以下命令查看(具体命令可能因版本而异)
# 通常信息会输出到日志或一个特定文件,例如:
cat /usr/local/sunlogin/bin/sunlogin.log | grep -i "code"
# 或者,如果提供了命令行工具:
sunloginclient --info

安装成功后,你需要在B机的图形界面(如果有的話)上,或者通过首次运行可能弹出的二维码/链接,使用手机向日葵APP扫码绑定账号。 对于纯命令行服务器,向日葵也提供了“向日葵SSH”功能,但本项目我们主要利用其远程桌面功能作为备用通道和安装验证手段,核心命令执行将依赖我们后面编写的脚本通道。

注意: 此步骤可能因向日葵官方安装包和版本更新而变化。如果官方提供了更稳定的安装脚本(如 .sh 脚本),应优先采用。核心目标是让B机的向日葵客户端处于运行状态,并确保A机可以通过向日葵软件远程连接到B机的桌面。

4. 实战步骤二:在A机构建自定义MCP服务器

这是本次实战的核心技术环节。我们需要在A机上创建一个MCP服务器,它提供一个工具,该工具能通过向日葵在B机上执行命令。

4.1 MCP服务器项目初始化

我们使用Python来快速构建一个MCP服务器,因为它有成熟的MCP SDK( mcp )。首先在A机上创建项目目录。

# 在A机上操作
mkdir openclaw-remote-installer-mcp
cd openclaw-remote-installer-mcp
python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate
pip install mcp

4.2 编写MCP服务器核心代码

创建一个名为 server.py 的文件,内容如下。这段代码实现了一个简单的MCP服务器,它提供了一个名为 install_openclaw_remote 的工具。

# server.py
import asyncio
import subprocess
import sys
from typing import Any
import mcp.server as mcp_server
from mcp.server.models import TextContent

# 创建服务器实例
server = mcp_server.Server("openclaw-remote-installer")

# 定义工具:远程安装OpenClaw
@server.list_tools()
async def handle_list_tools() -> list[mcp_server.Tool]:
    return [
        mcp_server.Tool(
            name="install_openclaw_remote",
            description="在远程计算机(通过向日葵识别码访问)上安装OpenClaw客户端。需要提供远程机的向日葵识别码和验证码(或已建立信任)。",
            inputSchema={
                "type": "object",
                "properties": {
                    "sunlogin_id": {
                        "type": "string",
                        "description": "远程计算机的向日葵识别码"
                    },
                    "sunlogin_pass": {
                        "type": "string",
                        "description": "远程计算机的向日葵验证码(临时)"
                    },
                    "remote_username": {
                        "type": "string",
                        "description": "远程计算机上的用户名",
                        "default": "user"
                    },
                    "remote_ip": {
                        "type": "string",
                        "description": "远程计算机的IP地址(可选,用于直接SSH备用方案)"
                    }
                },
                "required": ["sunlogin_id"]
            }
        )
    ]

# 处理工具调用
@server.call_tool()
async def handle_call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent]:
    if name == "install_openclaw_remote":
        sunlogin_id = arguments.get("sunlogin_id")
        sunlogin_pass = arguments.get("sunlogin_pass", "")
        remote_user = arguments.get("remote_username", "user")

        # 这里是核心逻辑:构造一个在远程机器上执行的命令。
        # 由于向日葵命令行控制能力有限,这里采用一个“迂回”策略。
        # 假设我们已经有一个脚本,能通过向日葵的API或adb-like命令向远程机发送指令。
        # 实际上,向日葵官方并未提供完善的命令行控制API。因此,我们这里演示一个概念性流程。
        # 更实际的方案是:假设B机已配置好SSH,且A机可通过局域网IP直接访问。
        # 我们将安装逻辑写在一个远程可执行的脚本里。

        # 步骤1: 生成一个在B机上执行的安装脚本
        install_script = f"""#!/bin/bash
        # 远程B机上的安装脚本
        echo \"开始在被控端(B机)安装OpenClaw...\"
        # 1. 安装Docker(如果尚未安装)
        if ! command -v docker &> /dev/null; then
            echo \"Docker未安装,正在安装...\"
            curl -fsSL https://get.docker.com -o get-docker.sh
            sudo sh get-docker.sh
            sudo usermod -aG docker $USER
            echo \"Docker安装完成。\"
        else
            echo \"Docker已安装。\"
        fi

        # 2. 拉取OpenClaw镜像(这里以某个公开镜像为例,实际请使用官方镜像)
        echo \"拉取OpenClaw Docker镜像...\"
        sudo docker pull someopenclaw/image:latest 2>/dev/null || echo \"镜像拉取失败,可能需手动指定正确镜像名。\"

        # 3. 运行OpenClaw容器(简化示例)
        echo \"尝试启动OpenClaw容器...\"
        sudo docker run -d --name openclaw-client -p 8080:8080 someopenclaw/image:latest || echo \"容器启动失败。\"

        echo \"安装流程执行完毕。请检查容器状态:sudo docker ps\"
        """

        # 步骤2: 将脚本传输到B机并执行
        # 由于直接通过向日葵命令行控制不现实,我们这里假设一个备用方案:使用SSH。
        # 前提是B机已开启SSH服务,且A机可以通过密钥或密码登录。
        remote_ip = arguments.get("remote_ip")
        if not remote_ip:
            return [TextContent(
                type="text",
                text=f"错误:未提供远程IP地址。当前仅实现了通过SSH的安装方式。请提供'remote_ip'参数。\n"
                     f"向日葵ID {sunlogin_id} 仅用于概念验证。实际部署需要集成向日葵的远程命令执行SDK(如果存在)。"
            )]

        # 使用ssh执行远程脚本
        ssh_command = f"ssh {remote_user}@{remote_ip} 'bash -s'"
        try:
            process = await asyncio.create_subprocess_shell(
                ssh_command,
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE
            )
            stdout, stderr = await process.communicate(input=install_script.encode())
            if process.returncode == 0:
                output = stdout.decode()
                return [TextContent(type="text", text=f"远程安装成功!输出:\n{output}")]
            else:
                error = stderr.decode()
                return [TextContent(type="text", text=f"远程安装失败!错误:\n{error}")]
        except Exception as e:
            return [TextContent(type="text", text=f"执行SSH命令时发生异常:{str(e)}")]

    return [TextContent(type="text", text=f"未知工具:{name}")]

async def main():
    async with server.run_stdio() as (read_stream, write_stream):
        # 服务器开始运行,通过标准输入输出与客户端通信
        await asyncio.gather(
            server._handle_messages(read_stream, write_stream),
        )

if __name__ == "__main__":
    asyncio.run(main())

代码解读与关键点:

  1. 工具定义 handle_list_tools 函数定义了一个名为 install_openclaw_remote 的工具,它需要参数如向日葵ID、验证码等。这定义了OpenClaw AI可以看到和调用的接口。
  2. 核心逻辑 handle_call_tool 函数是工具被调用时的处理逻辑。它构造了一个Bash脚本 install_script ,这个脚本包含了在B机上安装Docker和OpenClaw的所有命令。
  3. 通道选择 :代码中明确指出了 当前瓶颈 :向日葵并未提供成熟的命令行控制API来直接执行远程命令。因此,示例中采用了一个 备用方案 :通过SSH执行。这要求B机必须开启SSH服务,并且A机可以无密码登录(通过SSH密钥)。这实际上部分绕开了向日葵,但更符合生产环境自动化运维的实际做法(SSH是标准协议)。
  4. 安全警告 :将脚本通过 stdin 传给 bash -s 执行是一种常见方式,但需确保远程连接是可信的。

重要提示 :这个MCP服务器是一个 概念验证原型 。它揭示了通过MCP标准化远程安装指令的完整流程,但将“如何通过向日葵执行命令”这个最难的问题,暂时用SSH替代了。真正的“向日葵MCP”集成,需要等待向日葵官方提供命令行控制接口,或者通过逆向其客户端协议来实现,这超出了普通项目的范畴。本项目的主要价值在于 实现了MCP侧的标准化接口,并明确了与远程执行通道的对接点

4.3 测试MCP服务器

在A机上运行这个服务器,测试其是否能正常启动。

# 在A机的项目目录下
python server.py

如果程序没有报错并处于等待状态,说明MCP服务器已成功启动并通过stdio方式等待客户端连接。你可以按 Ctrl+C 终止它,因为我们接下来要把它集成到OpenClaw中。

5. 实战步骤三:将自定义MCP服务器接入OpenClaw

现在,我们需要在A机上配置OpenClaw,让它识别并使用我们刚刚编写的MCP服务器。

5.1 配置OpenClaw的MCP客户端

OpenClaw的配置通常位于 ~/.openclaw/config.yaml 或项目目录的 config.yaml 。我们需要在其中添加对我们自定义MCP服务器的引用。

假设你的OpenClaw是通过Docker运行的,或者本地安装了OpenClaw CLI。以下以修改配置文件为例:

# ~/.openclaw/config.yaml 或你的项目config.yaml
mcp_servers:
  # 其他已有的MCP服务器配置...
  remote_installer:
    command: "python"
    args:
      - "/绝对路径/to/your/openclaw-remote-installer-mcp/server.py"
    # 如果你的服务器需要虚拟环境,可以这样写:
    # command: "/绝对路径/to/your/openclaw-remote-installer-mcp/venv/bin/python"
    # args:
    #   - "/绝对路径/to/your/openclaw-remote-installer-mcp/server.py"
    env:
      # 可以传递一些环境变量
      PYTHONUNBUFFERED: "1"

配置解析

  • remote_installer :给这个MCP服务器起个名字。
  • command args :指定如何启动我们的MCP服务器。这里告诉OpenClaw,通过 python 解释器来运行我们的 server.py 脚本。
  • 确保提供的路径是 绝对路径 ,避免因工作目录问题导致找不到脚本。

5.2 启动OpenClaw并验证MCP工具

启动你的OpenClaw应用(无论是通过Docker-compose还是直接运行CLI)。启动后,OpenClaw会读取配置文件,并尝试启动我们配置的MCP服务器。

如何验证工具是否成功添加?这取决于你使用OpenClaw的方式。

方式一:通过OpenClaw CLI查询工具列表 如果OpenClaw提供了CLI命令来列出可用工具,可以尝试执行(具体命令请参考OpenClaw文档):

openclaw tools list

你应该能在输出列表中看到 install_openclaw_remote 这个工具。

方式二:通过AI界面直接调用 这是更直观的方式。在与你配置的AI模型(如Claude via OpenClaw)对话时,你可以直接说: “请调用 install_openclaw_remote 工具,在远程机器上安装OpenClaw。远程机的向日葵ID是123456789,IP地址是192.168.1.100,用户名是debian。”

如果配置正确,AI应该能识别到这个工具,并提示你输入所需参数。调用后,AI(实际上是背后的OpenClaw MCP客户端)会与我们的 server.py 通信,触发远程安装流程。

5.3 可能遇到的问题与排查

  1. MCP服务器启动失败 :检查OpenClaw日志,看是否有关于 remote_installer 的错误。常见原因是Python路径不对、脚本路径错误或脚本本身有语法错误。确保在A机上单独运行 python /path/to/server.py 是成功的。
  2. 工具未列出 :确认OpenClaw的配置文件名和路径正确,并且重启了OpenClaw服务以使配置生效。检查MCP服务器启动时是否输出了任何错误信息。
  3. SSH连接失败 :如果采用SSH备用方案,确保A机到B机的SSH连接是通的,并且配置了免密登录(使用SSH密钥)。可以在A机上手动执行 ssh user@B机IP 测试。
  4. 权限错误 :B机上的安装脚本需要sudo权限。确保按照3.1节配置了免密码sudo,或者脚本中妥善处理了密码输入(不推荐在自动化脚本中硬编码密码)。

6. 方案优化与进阶思考

上面的方案是一个可行的原型,但离真正的“一键远程部署”还有距离。我们可以从以下几个方向进行优化和深化。

6.1 实现真正的向日葵命令通道

要真正利用向日葵,我们需要找到一种非图形化的方式向B机发送命令。有几种探索方向:

  1. 向日葵命令行参数 :研究向日葵客户端 ( sunloginclient ) 是否支持 --command 或类似的参数来执行远程命令。查阅官方文档或使用 sunloginclient --help 仔细查看。
  2. 向日葵API :向日葵可能为商业版或企业版提供了REST API,可以用于远程管理。如果有API,我们可以用Python的 requests 库在MCP服务器中调用。
  3. 模拟用户输入 :作为“最后的手段”,可以考虑在A机上通过自动化工具(如 pyautogui )控制向日葵的远程桌面窗口,模拟键盘输入命令。这种方法极其脆弱,依赖界面布局,且不符合无头服务器的场景, 仅作为技术可能性提及,不推荐用于正式环境

如果找到了可靠的方法,我们只需要修改 server.py handle_call_tool 函数里执行命令的部分,将其替换为调用向日葵通道的代码即可,MCP服务器的接口和OpenClaw的配置完全不需要改动。这体现了MCP协议将“做什么”(接口)和“怎么做”(实现)解耦的优势。

6.2 增强MCP服务器的健壮性

目前的服务器非常简陋,需要增强以用于实际环境:

  • 错误处理 :增加更细致的错误捕获和分类,如网络超时、权限不足、软件源失败等,并返回更友好的错误信息给OpenClaw。
  • 安装状态查询 :增加一个 check_openclaw_status 工具,让AI可以查询B机上OpenClaw的运行状态(例如,通过SSH执行 docker ps | grep openclaw )。
  • 支持多种安装模式 :工具可以增加参数,让用户选择安装方式,如 method: docker method: native (本地安装),服务器根据参数生成不同的安装脚本。
  • 日志与审计 :将安装请求、执行结果、时间戳等信息记录到本地文件或数据库,便于回溯。

6.3 扩展为通用远程任务执行框架

这个项目的模式可以抽象出来。我们的MCP服务器本质上是一个 远程任务执行器 。我们可以将其改造成一个更通用的 remote_executor MCP服务器。

  • 通用工具设计 :定义一个 execute_remote_command 工具,参数包括 host_ip , command , working_dir 等。这样,AI就可以通过OpenClaw,在任意配置好的远程机器上执行任何命令,而不仅仅是安装OpenClaw。
  • 凭据管理 :将SSH密钥或向日葵认证信息存储在安全的配置文件中,而不是每次都在工具参数里传递,提高安全性。
  • 支持多主机 :在配置文件中维护一个远程主机列表,工具通过 host_name 来引用,而不是直接输入IP。

这样一来,OpenClaw就通过MCP获得了一个强大的“远程手”,可以管理整个服务器集群。

6.4 与CI/CD管道集成

在开发运维场景下,这个模式可以无缝集成到CI/CD中。例如,在GitLab CI或GitHub Actions的流水线中,一个步骤可以是“将新版本部署到测试服务器”。这个步骤可以触发一个脚本,该脚本通过调用OpenClaw的API(如果提供)或直接与MCP服务器交互,来执行我们编写的远程安装工具。这就实现了 通过AI智能体框架来驱动传统自动化部署 ,为运维流程增添了自然语言交互和智能决策的可能性。

通过这个“OpenClaw接入向日葵MCP实战”项目,我们不仅完成了一个具体的自动化安装任务,更重要的是,实践了一条将AI智能体能力通过标准化协议(MCP)延伸到物理设备管理领域的路径。虽然在与向日葵的深度集成上遇到了挑战,但整个架构已经打通,为未来集成更完善的远程控制协议(如Ansible、SaltStack等)提供了清晰的蓝图。下次当你需要给实验室的另一台电脑装软件时,或许只需要对AI说一句话就够了。

更多推荐