关于 ZennoDroid: device in ProjectMaker
ZennoDroid 的 Android MCP 服务允许 LLM 客户端控制与 ZennoDroid ProjectMaker 或任务运行器关联的设备。服务需单独运行,并配置 API key、目标类型和端点。
主要功能
- 01连接 ProjectMaker 或运行器设备
- 02选择编辑器或运行器目标
- 03配置 API key 和端点
- 04通过 stdio 或本地端口运行
适用场景
- 01操作 ProjectMaker 中的 Android 设备
- 02控制任务运行器使用的设备
- 03将 LLM 客户端连接到 ZennoDroid
MCP 相关
单独运行的 MCP.Android 服务向 MCP 客户端提供 Android 设备功能,并与 ZennoDroid PublicApi 通信。它支持 stdio 或本地监听端口,并使用配置的 API key。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
English | Русский
将 ZennoPoster 和 ZennoDroid MCP 服务连接到你自己的大模型客户端
这些 MCP 服务以独立的 win-x64 二进制文件形式通过 GitHub Releases 发布在共享仓库 https://github.com/ZennoLab/zennoposter-mcp/releases 中。每个服务都有自己的发布系列(使用各自的标签前缀):
- ProjectMaker(编辑器) — 标签
mcp-projectmaker-v*,压缩包MCP.ProjectMaker-v*-win-x64.zip - Instance(浏览器控制,双重挂载) — 标签
mcp-instance-v*,压缩包MCP.Instance-v*-win-x64.zip - ZennoPoster(任务运行器) — 标签
mcp-zennoposter-v*,压缩包MCP.ZennoPoster-v*-win-x64.zip - Android(ZennoDroid 设备) — 标签
mcp-android-v*,压缩包MCP.Android-v*-win-x64.zip
PublicApi 文档(使用 Redoc 呈现的 OpenAPI 契约、集成指南、错误代码和版本策略)位于 **https://zennolab.github.io/zennoposter-mcp/**(页面从此仓库的 docs/ 文件夹发布)。
这些服务支持 ZennoPoster 7.9.3 及更高版本和 ZennoDroid 2.6.1 及更高版本。MCP.Instance 仅适用于 ZennoPoster,MCP.Android 仅适用于 ZennoDroid;MCP.ProjectMaker 和 MCP.ZennoPoster 则适用于两者。
各服务版本对应的产品和契约版本:
**https://zennolab.github.io/zennoposter-mcp/compatibility.html**。
适用于 Cursor 和 VS Code 的安装按钮,以及每个服务对应的 Claude Code 命令: **https://zennolab.github.io/zennoposter-mcp/install.html**。
模型:使用你自己的密钥运行自己的 MCP 实例
产品本身会为内置 AI 聊天启动内部 MCP 服务——它们使用内部端口段 6107–6113(在 ZennoDroid 上所有端口均偏移 +10),从宿主获取遵循最小权限原则的服务密钥,并忽略传入请求的 Authorization 标头。这些属于内部基础设施:不支持从外部连接(那里的权限由服务密钥而非你的密钥决定),并且不得占用这些端口——如果其他进程占用了此端口段中的某个端口,内置服务将无法启动(产品会记录错误,但其 AI 系统将缺少该服务)。
这些内部服务没有自己的控制台,因此产品会将它们写入输出的所有内容复制到自己的日志中,每行前面都带有进程名称(MCP.ProjectMaker、Orchestrator 等)。普通的启动信息会标记为 Debug,不会写入日志;只有服务自身报告的警告或故障,以及服务意外退出时的退出代码,才会实际写入日志。内置聊天缺少某个服务时,应查看这里。
这些内部服务还需要一份每台机器独有的密钥,产品只会将其交给自己的 AI 进程,因此,即使能够访问端口,也不足以使用服务:没有密钥的调用会被拒绝并返回 401,且拒绝信息会以 ingress refused 记录到产品日志中。内置聊天自身在 6113 上的 API 也一样。如果你之前通过自己的客户端调用这些端口,请按下文所述,在公共端口段运行自己的副本。
对于你自己的大模型客户端,应从公共软件包运行 MCP 服务的独立副本:它会监听公共端口(见下表),并连接到同一个产品 PublicApi,但使用的是你自己的 ApiKey——其范围/级别由你在创建密钥时选择。两个副本可以并行运行,互不干扰。
在 ZennoDroid 上,适用于两个产品的两个服务监听的端口会高出 +10——MCP.ProjectMaker 使用 6217,MCP.ZennoPoster 使用 6220——与产品对内部端口段的偏移方式相同。这样,在同时安装了两种产品的机器上,两组服务可以同时运行。MCP.Android 仅适用于 ZennoDroid,仍使用 6211:ZennoPoster 上没有任何服务占用该端口。
默认端口,每个产品一张表。服务会从其 exe 同目录下的 appsettings.json 读取监听端口和 BaseUrl;标记为 ¹ 的端口没有此类默认值,需在命令行中与对应的 BaseUrl(以及 Target)一并传入,如步骤 3 的示例所示。
ZennoPoster
| 服务 | 端口 | 通信对象(PublicApi) | 配置中的键 |
|---|---|---|---|
MCP.ProjectMaker | 6207 | ProjectMaker :5299 | ProjectMaker:ApiKey |
MCP.Instance, Target=projectmaker(编辑器浏览器) | 6208 | ProjectMaker :5299 | Instance:ApiKey |
MCP.Instance, Target=zennoposter(任务浏览器) | 6209 ¹ | ZennoPoster :5300 | Instance:ApiKey |
MCP.ZennoPoster | 6210 | ZennoPoster :5300 | ZennoPoster:ApiKey |
ZennoDroid
| 服务 | 端口 | 通信对象(PublicApi) | 配置中的键 |
|---|---|---|---|
MCP.ProjectMaker | 6217 ¹ | ProjectMaker :5309 | ProjectMaker:ApiKey |
MCP.ZennoPoster | 6220 ¹ | ZennoPoster :5310 | ZennoPoster:ApiKey |
MCP.Android, Target=projectmaker(编辑器设备) | 6211 | ProjectMaker :5309 | Android:ApiKey |
MCP.Android, Target=zennoposter(任务设备) | 6212 ¹ | ZennoPoster :5310 | Android:ApiKey |
¹ 非内置默认值:需显式设置(--urls 加上对应的 BaseUrl;命令见步骤 3)。
所有设置都可通过标准 ASP.NET Core 配置进行覆盖:exe 同目录下的 appsettings.json、环境变量(ASPNETCORE_URLS、ProjectMaker__ApiKey,……)或命令行参数(--urls、--ProjectMaker:ApiKey=…,……)——命令行参数优先于环境变量,环境变量优先于 appsettings.json。
1. 下载所需的服务
在 releases 页面中找到所需服务的最新版本(按标签前缀查找),下载其 *-win-x64.zip 并解压到任意文件夹。
每个压缩包都包含一个独立运行的 .exe 和 appsettings.json;无需额外的 .NET 运行时。对于 Claude Desktop,请改用同一版本的 .mcpb 安装包,参见
Claude Desktop:从 .mcpb 安装包安装。
2. 生成 ApiKey
在 ProjectMaker 中:Settings → Api-Keys → Add new API key——此时会打开同名对话框:
- 设置
Label(任意键名,用于在列表中区分各个键)。 - 选择
Max tier(选择足以满足任务需求的最低级别——只读操作选 T0,修改操作选更高级别)。 - 勾选所需的
Scopes(默认仅勾选*:read;按需添加其他项)。 - 点击 Generate API Key——原始密钥只会显示 一次;请立即将其复制并妥善保存。
关于作用域/级别的更多信息,请参阅 security-model.md。
3. 使用你的密钥运行服务
密钥在 MCP 服务自身的配置中设置(而不是在 MCP 客户端的请求头中——该服务只接受来自环回地址的连接,且不会读取传入请求的 Authorization
请求头)。上表中端口后没有 ¹ 的服务,可以从其 exe 旁边的 appsettings.json 中的 ApiKey 获取密钥,并在不带参数的情况下启动;标有 ¹ 的端口始终通过命令行设置,同时还要设置对应的 BaseUrl(和
Target)。也可以像下面这样通过环境变量或参数传入密钥。只运行你需要的服务,并从对应产品的代码块中选择。
ZennoPoster
# ProjectMaker (editor): 6207 -> :5299
.\ZennoLab.AI.MCP.ProjectMaker.exe --ProjectMaker:ApiKey=zp_xxx
# Instance for the editor (PM browser): 6208 -> :5299
.\ZennoLab.AI.MCP.Instance.exe --Instance:ApiKey=zp_xxx
# Instance for the runner — a SECOND copy of the same exe: the port and the Target/BaseUrl pair are set explicitly
.\ZennoLab.AI.MCP.Instance.exe --urls http://localhost:6209 `
--Instance:Target=zennoposter --Instance:BaseUrl=http://localhost:5300/api/v1 `
--Instance:ApiKey=zp_xxx
# ZennoPoster (runner tasks/sessions): 6210 -> :5300
.\ZennoLab.AI.MCP.ZennoPoster.exe --ZennoPoster:ApiKey=zp_xxx
ZennoDroid
# ProjectMaker (editor): 6217 -> :5309
.\ZennoLab.AI.MCP.ProjectMaker.exe --urls http://localhost:6217 `
--ProjectMaker:BaseUrl=http://localhost:5309/api/v1 --ProjectMaker:ApiKey=zp_xxx
# ZennoDroid (runner tasks/sessions): 6220 -> :5310
.\ZennoLab.AI.MCP.ZennoPoster.exe --urls http://localhost:6220 `
--ZennoPoster:BaseUrl=http://localhost:5310/api/v1 --ZennoPoster:ApiKey=zp_xxx
# Android (the device attached to ProjectMaker): 6211 -> :5309
.\ZennoLab.AI.MCP.Android.exe --Android:ApiKey=zp_xxx
# Android for the runner — a SECOND copy of the same exe, for the devices of running tasks:
# the port and the Target/BaseUrl pair are set explicitly
.\ZennoLab.AI.MCP.Android.exe --urls http://localhost:6212 `
--Android:Target=zennoposter --Android:BaseUrl=http://localhost:5310/api/v1 `
--Android:ApiKey=zp_xxx
MCP.Android 会像 MCP.Instance 在 ZennoPoster 上那样挂载两次,原因相同:Android 域由 ProjectMaker 的 PublicApi(你在编辑器中看到的设备)和运行器的 PublicApi(任务正在驱动的设备)共同提供。和 MCP.Instance 一样,它需要一个 Target——编辑器设备使用 projectmaker,运行器使用 zennoposter——用于选择服务在初始化时交给 AI 的指令(一台 ID 可留为 0 的设备,或每个工作线程一台设备,ID 取自 list_devices);两种情况下工具集都相同。Target 和 BaseUrl 必须成对设置,与 MCP.Instance 完全相同(见下方说明)。Target 从 MCP.Android 0.4.0 版本开始提供;更早版本的区别仅在于 --urls 和 BaseUrl。
关于两份 MCP.Instance 和两份 MCP.Android 的重要说明:对于这些服务,Target(向 AI 提供哪类指令——关于 ProjectMaker 编辑器还是运行器)和 BaseUrl(HTTP 请求实际发往何处)只能成对配置,代码中不会将两者关联起来(Target=projectmaker → BaseUrl 指向 PM PublicApi 的 :5299,Target=zennoposter → BaseUrl 指向 ZP PublicApi 的 :5300;在 ZennoDroid 上则为 :5309 和 :5310)。启动时,服务会尽力通过目标主机的 /capabilities 进行检查,并在不匹配时记录警告;但如果目标主机在启动时无法访问,就会静默跳过检查——此时检测不到不匹配,AI 收到的指令会针对一个主机,而请求却发往另一个主机。
stdio:作为客户端子进程运行的服务
除监听端口外,每个服务还可以通过自身的标准输入和标准输出使用 MCP。使用 --stdio 启动 exe,由启动它的客户端管理连接:无需选择端口,机器上的其他程序无法访问该服务,而且多个客户端可以各自运行独立副本。MCPB 捆绑包和 Claude Desktop 使用此模式;Claude Code 和 MCP Inspector 也支持此模式。此模式适用于服务版本 0.5.0(ProjectMaker、ZennoPoster、Android)和 0.3.0(Instance)及更高版本。
只有 JSON-RPC 会写入标准输出;所有日志行都会写入标准错误。密钥照常从配置中读取;对于子进程,这意味着使用环境变量 <Section>__ApiKey(ProjectMaker__ApiKey、
Instance__ApiKey、ZennoPoster__ApiKey、Android__ApiKey);--<Section>:ApiKey= 参数和 exe 旁边的 appsettings.json 也可使用。Instance 和 Android 副本也以相同方式接收 Target 和 BaseUrl 配对设置(Instance__Target、Instance__BaseUrl 等)。
# Claude Code: -e stores the value in the server's own config entry, not in the launch command
# line - without it the key only reaches the server in this one session, from this one shell.
$env:ProjectMaker__ApiKey = "<your key>"
claude mcp add projectmaker --transport stdio -e "ProjectMaker__ApiKey=$env:ProjectMaker__ApiKey" -- "C:\mcp\ZennoLab.AI.MCP.ProjectMaker.exe" --stdio
对于读取 mcpServers 配置的客户端(Claude Desktop、Cursor),对应配置如下:
{
"mcpServers": {
"projectmaker": {
"command": "C:\\mcp\\ZennoLab.AI.MCP.ProjectMaker.exe",
"args": ["--stdio"],
"env": { "ProjectMaker__ApiKey": "<your key>" }
},
"instance-zp": {
"command": "C:\\mcp\\ZennoLab.AI.MCP.Instance.exe",
"args": ["--stdio"],
"env": {
"Instance__ApiKey": "<your key>",
"Instance__Target": "zennoposter",
"Instance__BaseUrl": "http://localhost:5300/api/v1"
}
}
}
}
客户端关闭标准输入时,进程就会结束。不使用 --stdio 时,一切照旧:服务按上述说明监听端口,产品内置的 AI 聊天仍通过 HTTP 使用服务。
Claude Desktop:从 .mcpb bundle 安装
每个服务端版本都包含对应的 MCPB bundle,每个 bundle 对应上表中的一个客户端名称,文件名为 MCP.<server>-<client name>-v<version>-win-x64.mcpb(例如 MCP.Instance-instance-zp-v0.3.0-win-x64.mcpb)。bundle 与 zip 中的 exe 相同,已针对 stdio 配置好正确的 Target 和 BaseUrl:Claude Desktop 会自行启动它,只需向你索取密钥。
| Bundle | 服务端 | 适用对象 |
|---|---|---|
projectmaker | MCP.ProjectMaker | ZennoPoster ProjectMaker,:5299 |
instance-pm | MCP.Instance | ZennoPoster ProjectMaker 的浏览器,:5299 |
instance-zp | MCP.Instance | 正在运行的 ZennoPoster 任务所用的浏览器,:5300 |
zennoposter | MCP.ZennoPoster | ZennoPoster 任务,:5300 |
projectmaker-droid | MCP.ProjectMaker | ZennoDroid ProjectMaker,:5309 |
zennodroid | MCP.ZennoPoster | ZennoDroid 任务,:5310 |
android-pm | MCP.Android | 连接到 ZennoDroid ProjectMaker 的设备,:5309 |
android-zd | MCP.Android | 正在运行的 ZennoDroid 任务所用的设备,:5310 |
- 从对应服务端的版本发布页面下载所需的 bundle。
- 在 Claude Desktop 中打开 Settings → Extensions,并将
.mcpb文件拖入窗口。 - 输入第 2 步中签发的 ApiKey。此字段为必填项:没有密钥,安装将无法完成。Claude Desktop 会将密钥保存在自身设置中;bundle 本身不含密钥。
- 启动 bundle 适用的产品。服务端的工具会显示在聊天中。
如需更换密钥,请在 Settings → Extensions 中打开该扩展并在那里修改。bundle 不会监听任何端口,因此不会与从 zip 启动的同一服务端副本发生冲突。
4. 配置你的大模型客户端
以下是 VS Code 的 .vscode/mcp.json 格式的现成配置片段。Cursor、Claude Code 和其他客户端的相同配置项,以及一键安装按钮,可在安装页面找到。
ZennoPoster
{
"servers": {
"projectmaker": {
"type": "http",
"url": "http://localhost:6207"
},
"instance-pm": {
"type": "http",
"url": "http://localhost:6208"
},
"instance-zp": {
"type": "http",
"url": "http://localhost:6209"
},
"zennoposter": {
"type": "http",
"url": "http://localhost:6210"
}
}
}
ZennoDroid — 其名称与 ZennoPoster 的名称不同,因此可在一个客户端中配置这两款产品:
{
"servers": {
"projectmaker-droid": {
"type": "http",
"url": "http://localhost:6217"
},
"zennodroid": {
"type": "http",
"url": "http://localhost:6220"
},
"android-pm": {
"type": "http",
"url": "http://localhost:6211"
},
"android-zd": {
"type": "http",
"url": "http://localhost:6212"
}
}
}
此连接环节无需授权:MCP 服务仅监听 loopback 地址,权限由服务端启动时使用的密钥决定(第 3 步)。
5. 验证连接
在 MCP 客户端中列出服务端的工具,然后调用一个需要密钥的只读工具:
| 服务端 | 工具 |
|---|---|
MCP.ProjectMaker | get_product_version |
MCP.ZennoPoster | tasks_list |
MCP.Instance | get_all_tabs,需打开浏览器 |
MCP.Android | list_devices |
ping 无需检查密钥即可响应,因此它只能表明服务端正在运行。MCP.ProjectMaker 和 MCP.ZennoPoster 上的 capabilities 会显示密钥可执行的操作——其 currentScopes 和 currentMaxTier;currentScopes 为空表示密钥未被接受或没有任何作用域。
如果密钥无效或缺少作用域/等级,调用会失败并返回结构化错误(unauthorized / forbidden,后者包含 required/current 字段)。MCP.Android 从 0.4.0 版本开始会返回此错误;更早的版本只会报告调用失败。
识别客户端:X-ZP-Client 标头
对 PublicApi 的每次 HTTP 调用都可以携带 X-ZP-Client 标头,以标识发起调用的客户端。其值采用 name/version 格式:
X-ZP-Client: mcp-zennoposter/0.6.0
四个官方 MCP sidecar 都会自动设置该标头:
| Sidecar | 值 |
|---|---|
MCP.ProjectMaker | mcp-projectmaker/<version> |
MCP.Instance | mcp-instance/<version> |
MCP.ZennoPoster | mcp-zennoposter/<version> |
MCP.Android | mcp-android/<version> |
**面向第三方集成方:**请选择一个稳定的小写标识符来命名您的产品,例如 acme-bot/1.0。避免使用通用名称(client、test、my-app),以免与其他集成方冲突。该标头的值可以自由填写,无需注册。
未携带该标头的调用(直接 HTTP 脚本、curl、未设置该标头的自定义客户端)会归属到内置客户端名称 direct-http。
该标头仅用于汇总分析——关于具体收集哪些数据以及不收集哪些数据,请参阅 data-collection.md。它不会影响路由、授权或速率限制。
更改端口
每个服务都有两个端口:一个用于监听 LLM 客户端的端口,另一个是它调用的产品 API 端口。
**监听端口。**以下三种方式均可设置,优先级从高到低依次为命令行参数、环境变量、配置文件:
.\ZennoLab.AI.MCP.ProjectMaker.exe --urls http://localhost:7207
$env:ASPNETCORE_URLS = "http://localhost:7207"
.\ZennoLab.AI.MCP.ProjectMaker.exe
或者,在 exe 同目录的 appsettings.json 中设置 "Urls": "http://localhost:7207"。更改监听端口后,请在第 4 步的客户端配置中更新对应 URL。
请勿使用 6107–6113(ZennoDroid 上为 6117–6123):这些端口属于产品内置服务,在其中任一端口上运行其他进程都会导致内置服务无法启动。
**产品 API 端口。**在该服务自己的配置节中设置 BaseUrl——可以使用类似
--ProjectMaker:BaseUrl=http://localhost:<port>/api/v1 的命令行参数、类似
ProjectMaker__BaseUrl 的环境变量,或在 exe 同目录的 appsettings.json 中设置 BaseUrl。第 3 步中的 ZennoDroid 命令正是这样设置的。
配置节以服务名称命名:ProjectMaker、Instance、ZennoPoster、Android。
MCP.ProjectMaker 和 MCP.ZennoPoster 的 0.3.0 及更早版本使用了 NeuroBot 和 ZennoPosterApi 这两个名称;较新版本仍支持这些名称,但服务会在启动时记录警告。
许可证
本仓库中的文件(文档和 OpenAPI 规范)采用 MIT 许可证。Releases 页面上的 MCP 服务二进制文件为专有软件;相关条款见 TERMS.md。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。