Let an AI agent run DedNets
DedNets ships an MCP server: point an AI coding agent at it and the agent
can enroll a machine, publish a service at a public HTTPS URL, and wire up a
watchdog, using the same API you would. It runs locally, out of the
dednetsctl binary, and talks only to your Console with a token you mint and
can revoke. (Since v0.4.1.)
1. Get the server
Section titled “1. Get the server”The MCP server is a subcommand of dednetsctl. Let npx fetch it for you,
download the CLI yourself, or install it with Homebrew.
Using Claude Code? Install the plugin in step 3 and skip this step entirely: it brings its own binary resolution.
| You want | Use | Because |
|---|---|---|
| Nothing installed system-wide | npx -y @dednets/mcp (Option A) |
follows your Console automatically, verified by sha256 |
A real, upgradable CLI on your PATH |
brew install dednets/tap/dednetsctl (Option C) |
one command, brew upgrade later; pinned to a version you choose |
| No Node and no Homebrew, or Windows | curl from /dist (Option B) |
works anywhere, and you manage upgrades |
Option A: npx, with nothing to install
Section titled “Option A: npx, with nothing to install”(Since v0.4.1. Needs Node 20.9 or newer, and a Console publishing v0.4.1 or newer.)
npx -y @dednets/mcp --probe-onlyThat downloads dednetsctl from your Console (DEDNETS_CONSOLE, default
https://console.dednets.com), checks it against the sha256 that Console
publishes, caches it under ~/.cache/dednets (%LOCALAPPDATA%\dednets\cache on
Windows) and exits without starting anything. Nothing is installed
system-wide, and the CLI always follows the Console you point at, including a
self-hosted one.
Run it once before wiring up an agent so the first session does not wait for the
download. Then use the npx configuration in step 3.
If it prints dednets mcp failed: console_too_old, that Console has not been
upgraded to v0.4.1 yet; use Option B against it, or ask whoever operates it to
upgrade.
Claude Code users should prefer the plugin (step 3) and can skip this step. Haunted Terminal users already have the CLI in the app bundle.
Option B: download the CLI
Section titled “Option B: download the CLI”Download it from your Console and put it on your PATH:
# macOS (Apple Silicon)curl -fsSLo dednetsctl https://console.dednets.com/dist/darwin-arm64/dednetsctl# macOS (Intel): .../dist/darwin-amd64/dednetsctl# Linux: .../dist/linux-arm64/dednetsctl or .../dist/linux-amd64/dednetsctlchmod +x dednetsctl && sudo mv dednetsctl /usr/local/bin/dednetsctl mcp -h # prints the flags; nothing is startedOn Windows, in PowerShell (curl there is an alias for Invoke-WebRequest
and takes different arguments, so call it by its real name):
$dir = "$env:LOCALAPPDATA\DedNets"New-Item -ItemType Directory -Force -Path $dir | Out-NullInvoke-WebRequest -Uri https://console.dednets.com/dist/windows-amd64/dednetsctl.exe ` -OutFile "$dir\dednetsctl.exe"& "$dir\dednetsctl.exe" mcp -hThe CLI is called dednetsctl since v0.4.1 (it was dedmeshctl). There is no
alias, and the old /dist/<platform>/dedmeshctl URLs no longer resolve, so
re-download it with the command above if you still have the old binary.
Builds are published for macOS (Apple Silicon and Intel), Linux (amd64,
arm64) and Windows (amd64, as dednetsctl.exe). (Windows and Intel-Mac
builds since v0.4.1.) Windows gets the CLI, not the host agent: a Windows
machine can drive your DedNets account, and the hosts you enroll still run
Linux or macOS.
The Windows build is cross-compiled and unit-tested, and has not been run on a
Windows machine by us. mcp itself is the portable part of the CLI: it writes
no files, opens no unix sockets and reads no config directory. Two areas are
built but unverified there: the mTLS client-identity commands (login,
client enroll, attach) write their key and certificate with POSIX file
modes Windows ignores, and attach never puts the console into raw or
virtual-terminal input mode, so interactive use would be line-buffered and
locally echoed. Colored output (view) needs Windows Terminal or PowerShell
7; legacy conhost.exe shows the escape codes literally.
Option C: Homebrew (macOS and Linux)
Section titled “Option C: Homebrew (macOS and Linux)”(Since v0.4.1.)
brew install dednets/tap/dednetsctldednetsctl mcp -h # prints the flags; nothing is startedThe formula covers macOS (Apple Silicon and Intel) and Linux (arm64 and amd64), and installs a single binary. There is no Homebrew formula for Windows: use Option B there.
A Homebrew install pins one CLI version, the one the formula was cut from,
and brew upgrade dednetsctl moves it. That is the difference from Option A,
where the CLI follows whichever Console you point at. Against an older
self-hosted Console a pinned CLI is exactly the case the version-skew warning
below is for, so expect it and read it rather than filing it as a bug.
2. Mint a scoped token
Section titled “2. Mint a scoped token”In the Console, go to Settings > API tokens > Create token. Name it
after the agent (claude-code), tick the scopes you want it to have, and copy
the dak_… secret: it is shown exactly once.
For the full onboarding journey below, tick Read-only, Manage hosts, Manage services and Manage watchdogs. For a token that can only look, tick just Read-only. What each scope unlocks: API tokens and scopes.
The agent holds this token. Give it the least you need, and revoke it from the same page when you are done.
3. Connect your agent
Section titled “3. Connect your agent”Claude Code
Section titled “Claude Code”Plugin (recommended)
Section titled “Plugin (recommended)”(Since v0.4.1. macOS and Linux; on Windows use the manual configuration below.)
# 1. tell Claude Code where your Console is and how to authenticateexport DEDNETS_CONSOLE=https://console.dednets.com # omit if you use the hosted Consoleexport DEDNETS_TOKEN=... # Console > Settings > API tokens
# 2. install the pluginclaude plugin marketplace add dednets/dednets-claude-pluginclaude plugin install dednets@dednetsThe plugin finds the CLI for you, in this order: $DEDNETSCTL, the Haunted
Terminal app bundle, then dednetsctl on your PATH. If you have the Haunted
Terminal, you can skip step 1 of this page entirely. It also brings a skill that
walks the parts the MCP tools cannot do themselves, such as running an enroll
command on the machine being enrolled.
Both variables are read when Claude Code starts, so restart it after changing
either one. /mcp then lists dednets.
Your Console’s Use with AI button shows these same three paths (plugin,
npx, curl) with your Console’s URL already filled in. (Since v0.4.1.)
With npx instead of an installed CLI
Section titled “With npx instead of an installed CLI”(Since v0.4.1.) If you took Option A in step 1, name npx as the command and
skip the binary entirely:
{ "mcpServers": { "dednets": { "command": "npx", "args": ["-y", "@dednets/mcp"], "env": { "DEDNETS_CONSOLE": "https://console.dednets.com", "DEDNETS_TOKEN": "dak_your_token_here" } } }}Add "-read-only" to args after the package name for a look-but-do-not-touch
server.
Manual configuration
Section titled “Manual configuration”Create .mcp.json in the project you work from:
{ "mcpServers": { "dednets": { "command": "dednetsctl", "args": ["mcp"], "env": { "DEDNETS_CONSOLE": "https://console.dednets.com", "DEDNETS_TOKEN": "dak_your_token_here" } } }}Or add it from the command line:
claude mcp add dednets \ --env DEDNETS_CONSOLE=https://console.dednets.com \ --env DEDNETS_TOKEN=dak_your_token_here \ -- dednetsctl mcpThen /mcp inside Claude Code should list dednets as connected.
Claude Desktop
Section titled “Claude Desktop”The same block goes in the app’s config file, which differs per OS. Claude
Desktop does not inherit your shell PATH, so give the absolute command
path in both cases, and restart the app after editing the file. That applies to
npx too: use the output of which npx (often /usr/local/bin/npx or a path
under ~/.nvm/) rather than the bare word. (Since v0.4.1.)
macOS and Linux
Section titled “macOS and Linux”~/Library/Application Support/Claude/claude_desktop_config.json:
{ "mcpServers": { "dednets": { "command": "/usr/local/bin/dednetsctl", "args": ["mcp"], "env": { "DEDNETS_CONSOLE": "https://console.dednets.com", "DEDNETS_TOKEN": "dak_your_token_here" } } }}Windows
Section titled “Windows”%APPDATA%\Claude\claude_desktop_config.json. Give the expanded absolute path
to the .exe (the config file is not a shell: environment variables such as
%LOCALAPPDATA% are not expanded inside it), and remember that JSON needs
every backslash doubled. (Since v0.4.1.)
{ "mcpServers": { "dednets": { "command": "C:\\Users\\you\\AppData\\Local\\DedNets\\dednetsctl.exe", "args": ["mcp"], "env": { "DEDNETS_CONSOLE": "https://console.dednets.com", "DEDNETS_TOKEN": "dak_your_token_here" } } }}Any other MCP client
Section titled “Any other MCP client”| Setting | Value |
|---|---|
| Transport | stdio |
| Command | dednetsctl, or dednetsctl.exe on Windows (absolute path if the client does not use your PATH) |
| Args | ["mcp"], or ["mcp", "-read-only"] to publish only the read tools |
| Env | DEDNETS_CONSOLE (your Console base URL), DEDNETS_TOKEN (your dak_… token) |
With npx instead, the command is npx and the args are ["-y", "@dednets/mcp"]
(add "-read-only" after that for the read tools only). The environment is the
same. (Since v0.4.1.)
4. Check it works
Section titled “4. Check it works”Ask the agent: “list my DedNets hosts”. It should call host_list and answer
with your fleet. If it says it has no such tool, see
Troubleshooting.
5. What the agent can do
Section titled “5. What the agent can do”| Ask for | It does | Needs scope |
|---|---|---|
| “add this machine to my network” | enrolls a host, then hands you the exact install command to run on it | Manage hosts |
| “which of my hosts are online?” | lists the fleet with versions and status | Read-only |
| “give this container a public HTTPS URL” | publishes an app and returns the https://… address |
Manage services |
| “open port 25565 for my game server” | a raw public port, or a port on your own gateway host | Manage services |
| “let host A reach host B’s database” | a proxy port; nothing becomes public | Manage services |
| “is my service healthy?” | status, uptime and health-check state for one target | Read-only |
| “alert me if my nightly backup stops running” | creates a watchdog and gives you the cron wiring | Manage watchdogs |
| “why did my watchdog alert last night?” | recent transitions, uptime buckets, likely causes | Read-only |
Ready-made workflows (slash commands)
Section titled “Ready-made workflows (slash commands)”The server also ships whole workflows as MCP prompts. In Claude Code they
appear as slash commands after / (type /dednets to filter); other clients
list them in a prompt picker. Each one is a checklist the agent follows, and
each takes optional arguments. (Since v0.4.1.)
| Command | Does | Arguments |
|---|---|---|
/dednets:onboard_host |
enrolls a machine and waits for it to come online | host, flavor |
/dednets:review_fleet |
read-only review of every host and what it serves | kind |
/dednets:publish_app |
exports a service and hands back the public address | app, host, proto |
/dednets:remove_host |
shows what breaks, then revokes after you confirm | host |
/dednets:troubleshoot_watchdog |
reads a monitor’s history and names likely causes | watchdog, range |
Arguments are optional: run the command with none and it asks you for what it
needs. With -read-only only review_fleet and troubleshoot_watchdog are
offered, because the others need a tool that changes something.
Prefer starting from the Console? The Hosts page has a Use with AI button (since v0.4.1) that opens this same setup plus ready-made prompts for adding, reviewing, and removing hosts - the same text these slash commands use. Copy one straight into your agent.
The agent cannot mint or revoke API tokens, change your account, or touch anyone else’s resources, whatever you ask it for.
6. A worked example
Section titled “6. A worked example”This is a real run, not an illustration. The prompt was “deploy this machine as a new mesh host, run an HTTP service on it, expose it at a public URL, and configure a watchdog for it”, given to an agent that had the DedNets tools and a shell on a fresh Linux VM, and nothing else. What it did:
- Enrolled the host. It picked the
systemdinstall flavor (the VM had no Docker) and got a one-time join token plus a ready-to-run command. - Ran the install command on the machine itself, over its shell. This is the step the agent cannot do on your behalf without access: it needs a shell on the target machine, or you paste the command yourself.
- Waited for the host to come online, checking the fleet.
- Started a small HTTP service on
127.0.0.1:8080as a systemd unit, then published it as appdemowithproto: httpandpublic: true. That returned anhttps://demo-<username>.<domain>address which answered200end to end. - Created a watchdog (5 minute period, 60 second grace) and wired a cron
entry that pings start, runs the check, then pings success or fail. The
watchdog read
upon the next ping.
It took about 50 turns and a few minutes. Give the agent shell access to the target machine, or be ready to paste one install command yourself.
Troubleshooting
Section titled “Troubleshooting”- The agent has no DedNets tools. Either the config file is not where the
client reads it, or
dednetsctlis not on the client’sPATH(Claude Desktop: use the absolute path). Restart the client after editing the config. - “no token” on startup.
DEDNETS_TOKENis missing from theenvblock. The server refuses to start without it. - A call was refused for scope. The error names the scope to add. You cannot widen an existing token: mint a new one with the extra scope and update the config.
- Everything 404s or answers nonsense.
DEDNETS_CONSOLEmust be the full base URL including the scheme (https://console.dednets.com). - A call fails with
console_outdated, or the log warns about versions (since v0.4.1). Thedednetsctlbinary and the Console are on different releases. On its first tool call the server prints one line on stderr naming both versions and keeps running; a call that needs an endpoint the Console does not have then fails with afix:line instead of a bare 404. Fix it from whichever side you control: ask the Console operator to upgrade, or reinstall the CLI from that Console -curl -fsSLO https://<console>/dist/darwin-arm64/dednetsctl(or thelinux-…/darwin-amd64/windows-amd64/dednetsctl.exepath for your machine). The same version with a different-<sha>suffix is not skew and is never reported. - My Homebrew CLI and my Console disagree on the version (since v0.4.1).
Expected:
brew installpins the release the formula was cut from, so a Console on a different release produces exactly the skew warning above. Runbrew upgrade dednetsctl. If the Console is the older side, upgrade it, or switch tonpx -y @dednets/mcp(Option A), which follows the Console. brew install dednets/tap/dednetsctlsays there is no available formula. That tap has not published a formula yet, or you have an old cached copy of it:brew updateand retry.- The install command the agent gives me fails to download. Install commands are generated for a console reachable over HTTPS on port 443. A self-hosted console on another port hands out a command whose download URL does not resolve; enroll that host from the Console’s own Deploy a daemon wizard instead.
- I want a look-but-do-not-touch setup. Add
"-read-only"toargs: only the read tools are published, so no tool call can change anything. - npx says
console_too_old(since v0.4.1). That Console publishes a release older than v0.4.1, from before the CLI was renamed, so there is nodednetsctlfornpxto fetch. Ask whoever operates it to upgrade, or install the CLI yourself with Option B in step 1 and point your client at the binary. - npx says
checksum_mismatch(since v0.4.1). The bytes downloaded did not match the sha256 that Console publishes. Nothing was run and the download was deleted. A Console being redeployed at that exact moment explains it, so retry once; if it repeats, do not use that download and tell whoever operates the Console. - The first npx run is slow. It is fetching a CLI of roughly 12 MB and
verifying it. Every later run reuses the cached copy until the Console
publishes a new version. Run
npx -y @dednets/mcp --probe-onlyonce to warm it before an agent host starts the server. - Windows: the client shows no DedNets server at all. Download the
.exepath (windows-amd64/dednetsctl.exe); the suffix-less file is not published and Windows would not run it. Inclaude_desktop_config.jsonevery backslash in the path must be doubled, or the JSON is invalid and the client drops the whole server entry without saying so.