English | Русский
Connecting the ZennoPoster/ProjectMaker MCP servers to your own LLM client
The MCP servers are published as self-contained win-x64 binaries via GitHub Releases inthe shared repository https://github.com/ZennoLab/zennoposter-mcp/releases. Eachserver has its own release line (its own tag prefix):
- ProjectMaker (editor) — tags
mcp-projectmaker-v*, archiveMCP.ProjectMaker-v*-win-x64.zip - Instance (browser control, dual-mount) — tags
mcp-instance-v*, archiveMCP.Instance-v*-win-x64.zip - ZennoPoster (task runner) — tags
mcp-zennoposter-v*, archiveMCP.ZennoPoster-v*-win-x64.zip - Android (ZennoDroid device) — tags
mcp-android-v*, archiveMCP.Android-v*-win-x64.zip
PublicApi documentation (the OpenAPI contract rendered with Redoc, the integrator guide,error codes, versioning policy) lives at https://zennolab.github.io/zennoposter-mcp/(the pages are published from the docs/ folder of this repository).
These servers talk to ZennoPoster 7.9.2 and newer and to ZennoDroid 2.6.1 and newer.MCP.Instance applies to ZennoPoster only and MCP.Android to ZennoDroid only; MCP.ProjectMakerand MCP.ZennoPoster apply to both.Which server version goes with which product and contract version:https://zennolab.github.io/zennoposter-mcp/compatibility.html.
Install buttons for Cursor and VS Code and the Claude Code commands for every server:https://zennolab.github.io/zennoposter-mcp/install.html.
The model: your own MCP instance with your own key
The product itself starts internal MCP servers for its built-in AI chat — they live onthe internal port band 6107–6113 (on ZennoDroid everything is shifted by +10), receive aleast-privilege service key from the host, and ignore the Authorization header ofincoming requests. This is internal infrastructure: connecting toit from outside is not supported (permissions there are defined by the service key, notyours), and its ports must not be occupied — a foreign process on a port from this bandprevents the built-in server from starting (the product logs an error, but its AI stack isleft without that server).
For your own LLM client you run a separate copy of the MCP server from the publicpackage: it listens on the public port band 6207–6211 and talks to the same productPublicApi (:5299 ProjectMaker / :5300 ZennoPoster), but with your ApiKey — with thescopes/tier you chose when issuing the key. Both copies run side by side withoutinterfering with each other.
On ZennoDroid the two servers that serve both products listen +10 higher — MCP.ProjectMakeron 6217, MCP.ZennoPoster on 6220 — the same shift the product applies to its internal band.That way a machine with both products installed can run both sets at once. MCP.Android exists onlyon ZennoDroid and keeps 6211: nothing on ZennoPoster occupies it.
Default ports (set in the appsettings.json next to the exe):
| Server | Port | Talks to | Key in config |
|---|---|---|---|
MCP.ProjectMaker |
6207 | PM PublicApi :5299 |
ProjectMaker:ApiKey |
MCP.Instance (Target=projectmaker) |
6208 | PM PublicApi :5299 |
Instance:ApiKey |
MCP.Instance (Target=zennoposter) |
6209 (convention, set explicitly) | ZP PublicApi :5300 |
Instance:ApiKey |
MCP.ZennoPoster |
6210 | ZP PublicApi :5300 |
ZennoPoster:ApiKey |
MCP.Android (ZennoDroid, editor device) |
6211 | ZDroid PM PublicApi :5309 |
Android:ApiKey |
MCP.Android (ZennoDroid, task devices) |
6212 (convention, set explicitly) | ZDroid ZP PublicApi :5310 |
Android:ApiKey |
The product API those servers call listens on different ports in the two products:
| Application | ZennoPoster | ZennoDroid |
|---|---|---|
| ProjectMaker | 5299 | 5309 |
| ZennoPoster | 5300 | 5310 |
The defaults above and the examples below are for ZennoPoster. On ZennoDroid each server needs bothits listen port and its BaseUrl set explicitly:
| Server | Port | Talks to | Key in config |
|---|---|---|---|
MCP.ProjectMaker |
6217 (set explicitly) | ZDroid PM PublicApi :5309 |
ProjectMaker:ApiKey |
MCP.ZennoPoster |
6220 (set explicitly) | ZDroid ZP PublicApi :5310 |
ZennoPoster:ApiKey |
MCP.Android (editor device) |
6211 | ZDroid PM PublicApi :5309 |
Android:ApiKey |
MCP.Android (task devices) |
6212 (set explicitly) | ZDroid ZP PublicApi :5310 |
Android:ApiKey |
Everything can be overridden through standard ASP.NET Core configuration: theappsettings.json next to the exe, environment variables (ASPNETCORE_URLS,ProjectMaker__ApiKey, …) or command-line arguments (--urls, --ProjectMaker:ApiKey=…, …) —arguments override environment variables, environment variables overrideappsettings.json.
1. Download the server you need
On the releases page find the latest release of the server you need (by tag prefix),download its *-win-x64.zip and unpack it into any folder.Each archive is a single self-contained .exe + appsettings.json; no additional .NETruntime is required.
2. Issue an ApiKey
In ProjectMaker: Settings → API Keys → Add — the "Add API key" dialog opens:
- Set a
Label(an arbitrary key name, to tell keys apart in the list). - Choose the
Max tier(the minimum sufficient for your tasks — T0 for read-only, higherfor mutating operations). - Tick the
Scopesyou need (only*:readare ticked by default; add others as needed). - Confirm — the raw key is shown once; copy it to a safe place immediately.
More on scopes/tiers — security-model.md.
3. Run the server with your key
The key is set in the MCP server's own configuration (not in the MCP client's headers —the server accepts connections from loopback only and does not read the Authorizationheader of incoming requests). The simplest way is to put the key into ApiKey in theappsettings.json next to the exe and start with no arguments; or pass it via environmentvariables / arguments:
# 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
# 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
.\ZennoLab.AI.MCP.Android.exe --urls http://localhost:6212 `
--Android:BaseUrl=http://localhost:5310/api/v1 --Android:ApiKey=zp_xxx
MCP.Android mounts twice for the same reason MCP.Instance does on ZennoPoster: the Androiddomain is served both by ProjectMaker's PublicApi (the device you see in the editor) and by therunner's (the devices its tasks are driving). Unlike MCP.Instance it has no Target, so the twocopies differ only by --urls and BaseUrl.
On ZennoDroid, the same two executables are started on the shifted ports and pointed at theZennoDroid API:
# ProjectMaker on ZennoDroid: 6217 -> :5309
.\ZennoLab.AI.MCP.ProjectMaker.exe --urls http://localhost:6217 `
--ProjectMaker:BaseUrl=http://localhost:5309/api/v1 --ProjectMaker:ApiKey=zp_xxx
# ZennoPoster tasks on ZennoDroid: 6220 -> :5310
.\ZennoLab.AI.MCP.ZennoPoster.exe --urls http://localhost:6220 `
--ZennoPoster:BaseUrl=http://localhost:5310/api/v1 --ZennoPoster:ApiKey=zp_xxx
Important note on the two MCP.Instance copies: for the Instance server, Target(which instructions it serves to the AI — about ProjectMaker or about ZennoPoster) andBaseUrl (where HTTP requests actually go) are configured only together, as a pair, andare not linked in code (Target=projectmaker → BaseUrl at the PM PublicApi :5299,Target=zennoposter → BaseUrl at the ZP PublicApi :5300). On startup the server makesa best-effort check via the target host's /capabilities and logs a warning on mismatch,but if the target host is unreachable at startup the check is silently skipped — amismatch is then not detected, and the AI gets instructions about one host while requestsgo to another.
4. Configure your LLM client
A ready-made configuration fragment (the format matches Claude Code's .mcp.json; use theequivalent for your MCP client if needed):
{
"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"
}
}
}
On ZennoDroid the entries are these — different names, so both products can be configured in oneclient, and no instance-* mount, which ZennoDroid does not have:
{
"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"
}
}
}
No authorization is needed on this leg: the MCP servers listen on loopback only, and thepermissions are defined by the key the server itself was started with (step 3).
5. Verify the connection
With any MCP client (or plain HTTP) call a safe read-only method and make sure it responds200 OK with the expected data — e.g. get_product_version/ping on the server you need.If the key is invalid or lacks a scope/tier, the server returns a structured error(401 unauthorized / 403 forbidden with required/current fields), not a silentfailure.
Changing ports
Each server has two ports: the one it listens on for your LLM client, and the product API port itcalls.
Listen port. Any of the three, arguments winning over environment, environment over the file:
.\ZennoLab.AI.MCP.ProjectMaker.exe --urls http://localhost:7207
$env:ASPNETCORE_URLS = "http://localhost:7207"
.\ZennoLab.AI.MCP.ProjectMaker.exe
or "Urls": "http://localhost:7207" in the appsettings.json next to the exe. After moving alisten port, update the matching URL in the client configuration from step 4.
Stay off 6107–6113 (6117–6123 on ZennoDroid): those belong to the product's built-in servers,and a foreign process on one of them prevents the built-in server from starting.
Product API port. Set the BaseUrl of that server's own section — this is what you change onZennoDroid:
# ProjectMaker API on 5309 instead of 5299
.\ZennoLab.AI.MCP.ProjectMaker.exe --ProjectMaker:BaseUrl=http://localhost:5309/api/v1 --ProjectMaker:ApiKey=zp_xxx
# ZennoPoster API on 5310 instead of 5300
.\ZennoLab.AI.MCP.ZennoPoster.exe --ZennoPoster:BaseUrl=http://localhost:5310/api/v1 --ZennoPoster:ApiKey=zp_xxx
The section is named after the server: ProjectMaker, Instance, ZennoPoster, Android.Versions up to 0.3.0 of MCP.ProjectMaker and MCP.ZennoPoster used NeuroBot and ZennoPosterApi;those names still work in later versions and the server logs a warning at startup.
License
The files in this repository (documentation and the OpenAPI specification) are licensed under theMIT License. The MCP serverbinaries on the Releases page are proprietary; their terms are inTERMS.md.