pb-hypernode-mcp
Manage disposable Hypernode Brancher preview environments: create sanitized prod-clone nodes, inspect and operate on them over SSH/rsync, and clean them up.
brancher_create — Spin up a new Brancher node for an app, wait for it to become reachable, run mandatory anonymization/sanitization (PII scrub, admin reset, sandboxed payments, git baseline), and return access/admin credentials.
brancher_list — List active Brancher nodes for a given Hypernode app, including host, IP, and uptime-based minutes.
brancher_delete — Delete a Brancher node, but only after a confirmation re-call (
confirm=True); defaults to safe lookup/prompt first.brancher_ssh_info — Return SSH connection details (host, user, port) for a node without opening a connection.
brancher_exec — Run arbitrary shell commands on a Brancher node over SSH, returning stdout/stderr/exit code.
brancher_put — Sync a local file/directory to a Brancher node via rsync over SSH.
brancher_apps — List every Hypernode app that has an API token configured locally, so you know which apps the server can operate on.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@pb-hypernode-mcpSpin up a Brancher preview for myapp with customer data sanitized"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
pb-hypernode-mcp
Client-side Claude Code plugin for Hypernode Brancher — spin up disposable, prod-clone preview environments, drive AI-assisted changes over SSH, view via your existing browser MCP.
Why
Brancher gives you a mutable, temporary copy of your production Hypernode (≤24h-old data, full toolchain, real infra — not a Docker approximation). The catch: it clones production wholesale, meaning live customer PII and real payment/API credentials come along by default, and the node gets a public URL. This plugin closes that gap — every node it creates is anonymized and sandboxed automatically, before it's ever reported ready, so "let the client's AI poke at a real prod clone" doesn't also mean "expose real customer data on the internet."
Related MCP server: hostwares-mcp
Setup
Three steps: install the plugin, tell it your Hypernode token, restart Claude Code.
1. Install the plugin
Type this directly into Claude Code (no terminal needed):
/plugin marketplace add ProxiBlue/pb-hypernode-mcp@latest
/plugin install pb-hypernode-mcp@pb-hypernode-mcpClaude Code fetches everything straight from GitHub — no downloading, no separate server to run, nothing to clone by hand.
@latest pins you to the newest tested release rather than whatever's mid-development on main. To pin to a specific version instead (for reproducibility, e.g. across a team), use its tag directly — check Releases for the current version number, then:
/plugin marketplace add ProxiBlue/pb-hypernode-mcp@vX.Y.ZIf Claude Code reports "already at the latest version" but you know a newer release exists, it's comparing version numbers, not git commits — re-running marketplace update does nothing if the version string didn't change between releases. Remove and re-add the marketplace to force a fresh fetch:
/plugin marketplace remove pb-hypernode-mcp
/plugin marketplace add ProxiBlue/pb-hypernode-mcp@latest
/plugin install pb-hypernode-mcp@pb-hypernode-mcp
/reload-plugins(If you'd rather run it from a terminal instead, the same commands work as claude plugin marketplace add ... / claude plugin install ....)
2. Add your Hypernode API token(s)
Hypernode API tokens are scoped per Hypernode, not account-wide — there's no single token that works across every app you manage. This plugin needs one token per Hypernode you want it to touch, set as a JSON object mapping <appname> to its token. It never gets stored anywhere by the plugin — you set it as an environment variable, the same way you'd set any password-like value.
Find each app's token in its Hypernode Control Panel, then in your terminal (before opening Claude Code):
export HYPERNODE_API_TOKENS='{"myapp":"token1","myapp2":"token2"}'Managing a single Hypernode? A one-entry map still works:
export HYPERNODE_API_TOKENS='{"myapp":"your-token-here"}'The map's keys ARE the allowlist — only apps with an entry here can be operated on. An app with no token configured raises a clear error rather than silently trying (and failing) with the wrong credentials.
Optional: skip admin-path auto-discovery for an app you already know. An app's admin path (backend.frontName in env.php) is fixed at Magento install time and doesn't change between Brancher clones — VERIFIED (2026-08-21) that runtime auto-discovery of it right after sanitization chases a genuine Hypernode-side async clone-sync race with no reliable upper bound (see Safety guardrails below for the full history). If you already know an app's admin path — check once via brancher_exec after any spin-up — set it once and every future brancher_create for that app skips the race entirely:
export HYPERNODE_KNOWN_ADMIN_PATHS='{"myapp":"/admin-custom"}'An app with no entry here falls back to the existing best-effort runtime discovery — this is purely additive, never required.
Tip: add this line to your shell's startup file (~/.zshrc or ~/.bashrc) so you don't have to re-type it every time.
3. Restart Claude Code
Close and reopen Claude Code so it picks up the token and connects to the plugin. You're ready to go.
Quick start
Just ask, in plain English:
"Spin up a Brancher preview for myapp so I can show the client the new category page layout."
Claude creates the node, waits for it to come online, sanitizes it (see Safety guardrails), and reports back:
node_name: myapp-eph482913
access_url: https://myapp-eph482913.hypernode.io/Realistic wait time: up to ~15-20 minutes. Hypernode's own Control Panel states new Brancher node setup can take up to 15 minutes before the node even becomes SSH-reachable, before sanitization runs on top of that — this is normal, not a stall. The wait is two separately-timed phases under the hood (Hypernode assigning the node a real ip, then SSH itself answering); on success the report includes ip_assigned_after_seconds/ssh_reachable_after_seconds so Claude can tell you where the time actually went. Claude will typically run this in the background (a background Agent/Task call) rather than blocking the session for the full duration, and report back once the node is ready.
(minutes_remaining is always None — no verified Hypernode API source for a remaining-minutes figure exists yet; see Limitations.)
From there, ask it to make a change and show you the result, or just say "clean up any leftover preview nodes" when you're done — Brancher bills by the minute whether or not anyone's looking at it.
What's in the plugin
skills/
├── brancher-spinup/ create a sanitized preview node, report access details
├── brancher-preview/ full loop: spin up -> change -> build -> screenshot
├── brancher-prototype/ fast prototype loop -> harvest to ticket -> destroy
└── brancher-cleanup/ list/flag/delete leftover nodes
src/pb_hypernode_mcp/ the MCP server (7 tools) — see MCP tools below
tests/ automated test suiteRequirements
A Hypernode account on a Falcons plan, with an API token from the Control Panel (Brancher is a Falcons-only feature).
allow_api_token_usageenabled on the app. Real accounts default this setting tofalse. Hypernode 403s any Brancher/financial API call — includingbrancher_create— until an owner/admin explicitly turns on "API token usage" for the app in the Control Panel (Configuration -> Settings). A 403 whose message mentions the "financial nature of the command" means this setting is off — it is not a bug in this plugin.SSH access to the Hypernode account's
appuser resolvable with no explicit-iflag — the plugin shells out to plainssh app@<node>.hypernode.io/rsync, so whichever keysshpicks by default (agent identities,~/.ssh/id_*, or an~/.ssh/configmatch) must already be the one registered with your Hypernode account. If your~/.ssh/configonly has per-app aliases (e.g.Host hypernode_myapp) rather than aHost *.hypernode.iowildcard, Brancher's generated hostnames (<appname>-eph<id>.hypernode.io) won't match any of them and ssh silently falls back to a key Hypernode doesn't recognize — see Troubleshooting.Python 3.11+ and
uvinstalled on the machine running Claude Code (Claude Code plugins are just code — this is the runtime they need).
MCP tools
All 7 tools are registered on the pb-hypernode-mcp server (src/pb_hypernode_mcp/server.py). brancher_exec and brancher_put shell out to the system ssh/rsync binaries using your already-configured local SSH agent/key — this plugin never holds or stores key material itself. Every tool that calls the Hypernode REST API resolves its token per-app from HYPERNODE_API_TOKENS; an appname with no entry in that map has nothing to authenticate with and the call fails with a clear error listing which apps ARE configured.
Tool | Purpose | Key arguments |
| The sole node-creation tool: enforces a mandatory label and Falcons-plan eligibility, then wraps create -> wait -> run mandatory sanitization (including pointing the node's own base URL/vhost at itself) -> report ready as one non-bypassable call. There is no separate "raw create" tool — it is structurally impossible to create a Brancher node through this plugin without sanitization running first. Never returns an |
|
| List active Brancher nodes for |
|
| Delete a Brancher node. Gated behind a |
|
| Return SSH connection details ( |
|
| Run a shell command on a Brancher node over SSH (shells out to the system |
|
| Sync a local file/directory to a Brancher node via |
|
| List every Hypernode | none |
Skills
brancher-spinup— spin up a disposable Brancher preview node cloned from production, with mandatory automatic sanitization, and report its access URL. Use when a client asks to preview a change on a real prod-clone environment before it ships. Wraps the singlebrancher_createtool call — never reproduces the create/wait/sanitize sequence by hand.brancher-preview— the full loop: spin up a node (via thebrancher-spinupskill), apply a code change (push a local diff withbrancher_put, or edit in place withbrancher_exec), run only the Magento build commands the change actually needs (decide_build_commands()insrc/pb_hypernode_mcp/preview_logic.py), view the result through whatever browser MCP tool is already in the session, then explicitly remind the user the node is still billing Brancher minutes. Use when a client wants an end-to-end look at a change on a disposable environment. Never deletes the node itself.brancher-prototype— a throwaway, explicitly non-standards prototyping loop: spin up a node (reusingbrancher-spinup), then for each idea capture the verbatim prompt inPROTOTYPE_NOTES.mdbefore implementing it, hack fast on the node only (skipping tests/PSR-12/DI — never on the local repo), and let the client view the result. At the end, harvest whatever was learned into a GitHub scoping ticket viasrc/pb_hypernode_mcp/prototype_logic.py's tested functions (locate_baseline_command(),harvest_diff_commands(),build_harvest_ticket_body(),split_ticket_payloads(),harvested_marker_command()), then destroy the node throughbrancher-cleanup's confirm-before-delete flow. Use when a client wants to fast-prototype ideas on a preview node without production-grade code, bundling results into a scoping ticket. The prototype code always dies with the node — the ticket is the sole surviving artifact, opened with aNEVER_MERGE_MARKERso nobody mistakes the diff for something ready to merge.brancher-cleanup— list active nodes withbrancher_list, flag any at or past an age threshold (minutes >= threshold_minutes, default 240 minutes / 4 hours, viaflag_stale_nodes()insrc/pb_hypernode_mcp/cleanup_logic.py), and delete flagged nodes (single or bulk) only after explicit user confirmation. Before any flagged node reaches a delete confirmation, it also checks that node for un-harvestedbrancher-prototypework (has_unharvested_changes()insrc/pb_hypernode_mcp/prototype_logic.py) and warns the user inline (changed-file/commit counts, or the recorded ticket URL if already harvested) — informational only, it never blocks or skips the confirmed deletion. Use when a client wants to check for or remove leftover Brancher nodes to stop minute accrual. Brancher bills wall-clock minutes from creation regardless of whether anyone is actively using the node.
Multiple Hypernodes
Every Hypernode needs its own entry in HYPERNODE_API_TOKENS — there is no account-wide token. All four skills call brancher_apps first whenever a request doesn't say which app to target, show the configured list, and ask before doing anything else; they never guess an appname. If only one app is configured, they proceed with it and just say so, rather than asking a pointless confirmation question.
Safety guardrails
Mandatory sanitization — cannot be disabled. Every
brancher_createcall runs the full sanitization sequence (src/pb_hypernode_mcp/sanitization/) against the node before it is ever reported"ready"or returns anaccess_url. There is no flag, config option, or bypass path —brancher_createis the ONLY node-creation MCP tool this plugin registers (there is no separate, unsanitized create tool), andspinup_sanitized_brancher_node()insrc/pb_hypernode_mcp/tools/brancher_spinup_flow.py(the function behind it) structurally cannot return an access URL without every sanitization command having exited 0 first. If a sanitization command fails partway through, the tool raisesSanitizationFailedErrorand deliberately withholds the access URL — the exception does not even carry it, so a catching caller has no way to accidentally surface it.The sequence (config-driven, Magento-shaped default in
sanitization/config.py::DEFAULT_MAGENTO_SANITIZATION_CONFIG):Base URL + vhost + Basic Auth setup — a freshly cloned Brancher node keeps the originating app's base URL and has no nginx vhost at all for its own new ephemeral hostname (Hypernode's own documented behaviour — see "Brancher Install Hook" in their docs).
bin/magento config:set web/unsecure/base_url/web/secure/base_urlare forced to the node's ownhttps://<node>.hypernode.io/at the default scope, at each website scope inSanitizationConfig.base_url_website_scope_codes(defaults to('base',), Magento's own default website code), and at each admin store scope inbase_url_admin_store_scope_codes(defaults to('admin',), a DIFFERENT scope type than the website one) — VERIFIED live:env.phpcarried independent stale overrides at BOTH scope types, each winning over the default-scope value for requests resolving through it. At the admin store scope specifically,base_link_url/base_static_url/base_media_urlare ALSO overridden individually, not justbase_url— VERIFIED live: unlike the default/website scopes (where those three are{{secure_base_url}}...templates that auto-resolve), this account's admin scope had all three MATERIALIZED as literal hardcoded URLs, so the admin login rendered completely unstyled (broken CSS/JS/media) until each was overridden explicitly.admin/url/use_customis also forced off (disable_custom_admin_url, defaultTrue) — VERIFIED live as the actual root cause of an admin login that 404s even with everything else correctly wired: Magento's admin router refuses to serve the admin area on any hostname other than a configured custom admin domain, which a Brancher node's ephemeral hostname can never match. The cache is flushed; an HTTP Basic Auth gate is installed (see Safety guardrails below); and (ifvhost_webrootis set — defaults to Hypernode's standard single-app/data/web/publiclayout)hypernode-manage-vhostscreates the vhost. Setvhost_webroot=Noneto skip vhost creation for a multi-app-per-domain layout; set either scope-codes tuple to()to skip that pass for an app with no such override.PII anonymization —
UPDATEstatements (vian98-magerun2 db:query) againstcustomer_entity,customer_address_entity,sales_order,sales_order_address(names/emails/phones/street replaced with anonymized placeholders), and stored card data (quote_payment,sales_order_payment:cc_number_enc/cc_owner/additional_datanulled —sales_order_paymenthas nocc_cid_enccolumn on a real Magento schema at all, CVV is never stored post-order per PCI-DSS, onlyquote_payment's pre-order schema has it).Admin credential reset — every
admin_userrow gets its password overwritten with a hash that is deliberately invalid for any real password (locks form-based login on that account — seeadmin_password_notein the result), and its username/email replaced with a per-row-unique sanitized value (admin_user.usernamecarries a unique index — a bare literal on a bulk update would violate it on any account with more than one admin row). A second,where-scoped update (SanitizationConfig.admin_primary_user_reset) then overrides exactly one deterministic row back to the literaladmin/admin@example.invalididentity reported in the result asadmin_username/admin_email. A genuinely usable login is then provisioned separately — see the next bullet.Real admin login provisioning —
bin/magento admin:user:createcreates a brand-new admin account (default usernamepreview, distinct from the renamed-and-locked original above, so there's no collision) with a fresh random password (SanitizationConfig.preview_admin_username, default'preview'; set toNoneto disable). Reported aspreview_admin_username/preview_admin_password— this is the account to actually log in with, notadmin_usernameabove.Payment gateway sandbox-forcing — forces e.g.
payment/braintree/environment=sandbox(PayPal-via-Braintree is covered by the same setting; a real Magento 2.4.9 install has no workingpaypal/general/sandbox_flagat all — legacy PayPal Standard/Express convention, verified absent).Third-party API key stubbing — replaces live keys (e.g. AvaTax) with dummy sandbox values so no preview node can make a real charge or a real third-party API call under production credentials. ShipperHQ is deliberately excluded from this list (explicit client decision) — it stays on its live/production setting on every node, since it has no "developer mode" distinction to force it into.
Git baseline for AI-driven edits — a client's AI makes code changes over SSH against this node;
generate_git_baseline_commands(sanitization/commands.py) writes anAI_INSTRUCTIONS.mdat the app root (explains what the environment is, why the git branch exists, and its limits — ephemeral node, anonymized data, sandboxed gateways, excluded build-artifact paths, never push this branch), then initializes a git repo if one doesn't already exist (reuses one if Hypernode Deploy already manages this app via git, rather than destroying its history), strips any configured remote (defense against an AI later accidentally pushing to a real origin), checks outSanitizationConfig.git_baseline_branch(default'brancher-preview'), and commits every file EXCEPTvendor/,generated/,var/,pub/static/,pub/media/,node_modules/(build artifacts, not source) as a baseline snapshot. Runs LAST in the sequence so the snapshot reflects the node's genuinely final, fully-sanitized state. The commit uses--allow-emptyso it can never fail with "nothing to commit".git_baseline_enabled=Falsedisables the whole step. Gives the developer a real audit trail (git diff/git logagainst this baseline) of exactly what the AI changed during the preview session.
Steps 4 and 5 write directly to
core_config_datavia a raw SQL UPSERT rather thanbin/magento config:set— VERIFIED (2026-08-20) against a real Braintree install thatconfig:setvalidates the path against system.xml-declared admin-UI fields and refuses a genuinely real, actively-used config path with "doesn't exist". Magento's runtime config reader has no knowledge of system.xml and reads raw DB rows directly, so the UPSERT achieves the actual sanitization goal without fighting that unrelated validation layer. A trailingcache:flushruns once afterward so the sandboxed values are actually served.Each command gets a bounded retry (3 attempts, 5s apart by default) if it hits a connection-level failure — verified live: a DNS record for a freshly created node can flap even after the SSH-reachability probe already succeeded once. A command that ran and returned a non-zero exit code is never retried (a real command failure, not a connectivity blip) — it fails
SanitizationFailedErrorimmediately.After all commands succeed,
brancher_createmakes a best-effort (non-blocking) call ton98-magerun2 info:adminurito report the node's actualadmin_url— UNLESSHYPERNODE_KNOWN_ADMIN_PATHSalready has an entry for this app, in which case that value is used directly and this whole discovery step is skipped. History, for context: VERIFIED (2026-08-20/21) against multiple real Brancher nodes across several rounds that the underlying cause is Hypernode's own asynchronous clone/deploy process still finishing its file sync (the app's real adminfrontName, inapp/etc/env.php) in the ~70+ seconds AFTER SSH already reports reachable — hard filesystem-timestamp evidence, not a guess. Three successive attempts at closing this via timing alone each failed on live re-test: a two-consecutive-matching-reads check (v0.4.4), switching frombin/magentoton98-magerun2 info:adminurion the belief the latter read more reliably (v0.4.6 — disproven the next day, n98-magerun2 hits the exact same stale-read window), and a 90s settle delay before the first read (v0.5.1 — still reproduced on a clean run withsanitization_commands_runconfirming full completion). Rather than continue chasing an apparently-unbounded race,known_admin_path/HYPERNODE_KNOWN_ADMIN_PATHS(v0.5.2) sidesteps it entirely for any app whose admin path is already known — it's fixed at install time and never changes between clones of the same source app, so it never actually needed runtime rediscovery. For a first-time/unknown app, the existing best-effort dynamic resolution still runs (retried on ANY of exception / non-zero exit_code / unparseable stdout,admin_path_resolve_retries/admin_path_resolve_retry_delay_seconds/admin_path_resolve_settle_seconds) and falls back to/adminif it never resolves — never fails spin-up either way.A real client app's exact table shape and installed integrations should override/extend
SanitizationConfig, not rely on the shipped default in production — it exists as a safe-by-default starting point, not a promise it matches every schema.Per-app token allowlist (
HYPERNODE_API_TOKENS) — the map's keys ARE the allowlist.brancher_create,brancher_list,brancher_delete, andbrancher_ssh_inforefuse anyappnamewith no configured token — there is no separate allowlist mechanism to fall out of sync with the token map.Falcons-plan eligibility check —
brancher_createrejects apps not on a Brancher-eligible plan before creating anything.-eph-only guard —brancher_execandbrancher_putvalidatenode_nameagainst the<appname>-eph<id>pattern (tools/_guards.py::validate_eph_node_name,.fullmatch()— no partial-match or trailing-character gaps) before opening any SSH connection or subprocess. It is structurally impossible to point either tool at a production hostname.Confirm-before-delete —
brancher_deletenever deletes on the first call. It requires an explicitconfirm=Truere-call after showing the target node's details; a threshold being configured or a node being flagged as stale is never itself confirmation.Mandatory label —
brancher_createrejects calls with nolabels, so every node is traceable to a reason/ticket.Token handling —
HYPERNODE_API_TOKENSis read from the environment only and is never written to disk or plugin config by this plugin. Each Hypernode's token is only ever used to authenticate requests for its own app.brancher_putargument hardening —remote_path/local_pathare shell-quoted and rsync runs with--protect-args, so the remote host's shell never re-parses a path argument, closing off metacharacter injection via a crafted path.
This design was checked by a 3-specialist security review before release (static analysis, adversarial testing, defensive audit). It caught a real critical gap in an earlier draft — the sanitized flow had been built as a second tool alongside a still-exposed raw, unsanitized create path — which is why "one creation tool, no exceptions" is called out so insistently above. Found a security issue? Open an issue rather than a PR with the exploit details.
Limitations (v1)
Basic Auth on the new vhost (resolved, 2026-08-20). A vhost freshly created by
hypernode-manage-vhostsdoes NOT inherit the parent app's own Basic Auth — an earlier investigation this session wrongly concluded there was no self-service fix (checkedhypernode-manage-vhosts --help,hypernode-systemctl settings, and every/etc/nginx/config file readable by theappuser; missed the actual documented mechanism). The real fix, per docs.hypernode.com's "How to Protect Your Magento Store With a Password in Nginx":/data/web/nginx/(app-owned, under$HOME) is Hypernode's own self-service nginx-include directory —brancher_createnow writes anhtpasswdfile there viahtpasswd -cband aserver.basicauthsnippet restricting the challenge to exactly the node's own hostname ($http_hostmatch), both BEFORE the vhost is created so the include is picked up from the vhost's very first generation. SetSanitizationConfig.basic_auth_username = Noneto disable. Credentials are reported back aspreview_basic_auth_username/preview_basic_auth_password— a fresh, random (secrets.token_urlsafe) password every spin-up, never a fixed shared one.Magento/Mage-OS only. The sanitization layer's default config (
DEFAULT_MAGENTO_SANITIZATION_CONFIG) and thebrancher-previewskill's build-command decision logic (decide_build_commands()) are both Magento-shaped. This is not a generic multi-platform tool — WooCommerce, Shopware, Laravel, and other Hypernode-hosted platforms are out of scope for v1. A non-Magento app would need a hand-writtenSanitizationConfigat minimum, and the preview skill's build sequence would not apply.No MCP-managed SSH keys.
brancher_exec/brancher_putshell out to the systemssh/rsyncbinaries and rely entirely on your own local SSH agent/key already having access to Brancher nodes (which inherit access automatically via Brancher's full-filesystem clone from production). This plugin never provisions, stores, or transmits key material.stdio transport only. No remote/HTTP MCP transport in v1 — this is a local Claude Code plugin, run per-developer against their own
HYPERNODE_API_TOKENS. There is no hosted/managed version of this MCP. Token and SSH access are both entirely client-owned.REST API only. No Hypernode Deploy (
deploy.php) integration in v1.Wall-clock, not idle-aware, minute accounting.
brancher-cleanup's staleness check usesminutesas reported by the Hypernode API (uptime since creation) — it cannot tell an idle node from an actively used one.The reachability wait is two explicit phases, not one blind SSH-poll loop. Earlier versions started retrying SSH immediately after create, even while the node had no ip at all yet — every poll was guaranteed to fail until Hypernode's own provisioning finally assigned one, and a timeout only ever surfaced as a single generic "never became reachable" error with no way to tell "Hypernode's infra never gave us a host" apart from "we had a host but SSH never answered".
spinup_sanitized_brancher_nodenow splits the wait: phase 1 polls the Brancher list endpoint (a plain REST call, no SSH, reusingbrancher_list'sipfield) until the node has a real ip, raisingNodeIpNeverAssignedErroron timeout; phase 2 then polls SSH with whatever's left of the 1200s (20 min) ceiling, raisingNodeUnreachableTimeoutErrorif the ip showed up but SSH itself never answered. The two phases share that one ceiling — phase 2 does not get a fresh timeout of its own on top of phase 1. On success both phase durations (ip_assigned_after_seconds,ssh_reachable_after_seconds) are returned so a slow spin-up can be reported back to Hypernode support with real numbers instead of "it just timed out".Plan-eligibility field verified; minutes-remaining has no known source.
brancher_create's Falcons-plan eligibility check is confirmed against a real Hypernode account (GET /v2/app/<appname>/): the field isproduct.code(e.g."FALCON_S_202603DEV", matched as a"FALCON"substring since Hypernode has multiple Falcon SKUs — not aplan_typefield, and not an exact-value match). The earlierminutes_remainingfield name (brancher_minutes_remaining) was not just misnamed but nonexistent — there is no verified field or endpoint anywhere on the Hypernode API for an account-wide remaining-minutes figure, socreate_brancher_nodealways returnsminutes_remaining: None.Brancher endpoints, response shapes, and node-name ID charset: now VERIFIED, not guessed (2026-08-19). Confirmed via two independent sources — a live
curlagainst a real Hypernode account's Brancher list endpoint, and the officialByteInternet/hypernode-api-pythonclient library's source (hypernode_api_python/client.py).Real, non-deprecated endpoints: list is
GET /v2/brancher/app/<appname>/, create isPOST /v2/brancher/app/<appname>/, destroy isDELETE /v2/brancher/<name>/(a different top-level path — not nested under/v2/app/<appname>/at all). The old/v2/app/<appname>/brancher/shape still works but returns an API deprecation warning.List response: the node array is under a top-level
brancherskey, notnodes. Each entry hasname,ip(null until ready),created,elapsed_time(wall-clock seconds since creation), andcost(minutes billed) — nohostfield (brancher_listderives it asf"{name}.hypernode.io") and nominutesfield (brancher_listderives it aselapsed_time // 60).Create response: the node-name field is
name, notappname(confirmed against the official client library's own docstring example, e.g.{"name": "yourappname-ephoj82yb", ...}).Node readiness:
brancher_ssh_inforeadsip, notip_address(confirmed via live curl onGET /v2/app/<appname>/).-eph<id>suffix charset: lowercase-alphanumeric, not digit-only — both a real account's node (ppsdev-ephp8b5c2) and the official client library's own examples (yourappname-ephoj82yb) show alphanumeric suffixes.
Brancher/financial API calls require
allow_api_token_usage: true. This is an account-level setting (Hypernode Control Panel -> Configuration -> Settings, owner/admin only), not a code path in this plugin — see Requirements.Playwright test offloading not yet built. Running the functional test suite against a Brancher node instead of local/CI is tracked separately — see ProxiBlue/pb-hypernode-mcp#1 or the originating design ticket.
brancher-prototype's never-merge/harvest discipline is prompt-level enforcement, not a structural sandbox. The "hack fast, on-node only" ground rules and the harvest ticket'sNEVER_MERGE_MARKERare prose asking the AI not to merge prototype code or edit the local repo instead of the node — nothing here makes either mistake structurally impossible, unlike the sanitization-invariants and no-credentials limitsbrancher-prototypetreats as genuinely non-suspendable.After upgrading the plugin, a full session restart is required —
/reload-pluginsalone is not enough. A marketplace update deletes/replaces files out from under the still-running MCP server subprocess, which keeps serving the OLD version's code (with dangling file handles) until the whole Claude Code session, not just the plugin, is restarted. To confirm which version is actually loaded, cross-check thesanitization_commands_runcount a freshbrancher_createreports against the count expected for the version you bumped to — don't trust the number inplugin.jsonalone.
Troubleshooting
NodeUnreachableTimeoutErroreven though the node IS actually reachable (verified 2026-08-20). If a manualssh app@<node>.hypernode.ioworks fine butbrancher_createstill times out waiting on SSH, suspect an SSH key mismatch, not a Hypernode infra problem.brancher_exec/brancher_putshell out to plainssh/rsyncwith no-iflag (see Requirements) — they rely entirely on whichever keysshpicks by its own default resolution. Two common causes:Your
~/.ssh/configonly defines per-app aliases (Host hypernode_myapp,Host hypernode_myappdev, ...) rather than a wildcard. Those aliases only match when you literally typessh hypernode_myapp— they do not match the real generated hostnamemyapp-eph<id>.hypernode.iothat Brancher nodes actually use, sosshfalls through to your default identity instead, which may not be the key registered with your Hypernode account.Fix: add a wildcard block to
~/.ssh/configso it matches every Brancher-generated hostname automatically, using whichever key is actually registered with your Hypernode account (Control Panel -> Configuration -> SSH keys):Host *.hypernode.io User app IdentityFile ~/.ssh/your_hypernode_key IdentitiesOnly yesTo confirm this is the actual cause before editing anything:
brancher_listthe stuck node to get itsip/hostname, then runssh -v app@<hostname>.hypernode.io echo okby hand.Connection refusedor a hang mid-negotiation is genuine Hypernode-side node instability (see theNodeIpNeverAssignedError/NodeUnreachableTimeoutErrordistinction in Limitations); an immediatePermission denied (publickey,password)with no-iflag confirms it's a local key-selection issue, not the node.
A brand new node serves nginx's default page, not your app, even after
brancher_createreportsstatus: "ready". This should no longer happen as of v0.3.0 —brancher_createnow runs Hypernode's own documented base-URL/vhost setup (see the Safety guardrails section) as part of the mandatory sanitization sequence. If you still see this on a current version, check the node'ssanitization_commands_runcount in the result — a low/unexpected count together with aSanitizationFailedErrormeans the vhost step itself failed (commonly:SanitizationConfig.vhost_webrootdoesn't match your app's actual deploy layout — see the field's docstring insanitization/config.py)./plugin marketplace updatereports success but nothing actually changed. Claude Code compares theversionfield inplugin.json, not the git commit — moving thelatesttag to a new commit without bumpingversionsilently no-ops for anyone already installed. If you maintain a fork, always bump bothpyproject.tomland.claude-plugin/plugin.jsonbefore moving tags (see Cutting a release).
Development
git clone https://github.com/ProxiBlue/pb-hypernode-mcp
cd pb-hypernode-mcp
uv sync --extra dev
uv run pytest -v # mocked HTTP/SSH — no real Hypernode account touched
uv run ruff check src tests # lint
uv run ruff format --check src tests # format check
uv run pyright src tests # type checkNo integration tests run automatically against a real Hypernode account. If you're changing tools/brancher_exec.py or the reachability-polling logic in tools/brancher_spinup_flow.py, do a manual smoke test against a real Falcons-plan node before merging — mocks can't catch a wrong SSH-user assumption or a shape mismatch in the real API response.
To install your own clone for local development instead of the published version, point Claude Code at the folder directly:
claude plugin marketplace add pb-hypernode-mcp /path/to/your/clone
claude plugin install pb-hypernode-mcp@pb-hypernode-mcpAfter editing skills or server code, run claude plugin update pb-hypernode-mcp@pb-hypernode-mcp to pick up the change without re-adding the marketplace.
If the plugin doesn't show up after installing, check: claude plugin list shows pb-hypernode-mcp as enabled; a fresh Claude Code session lists the brancher_* tools and the four brancher-* skills; HYPERNODE_API_TOKENS is set in the same shell you launched Claude Code from.
Cutting a release
Bump version in both pyproject.toml and .claude-plugin/plugin.json — Claude Code's /plugin marketplace update compares plugin.json's version string, not the git commit. Moving latest without bumping this means installed users get told "already at the latest version" even though the underlying code changed. Then:
git tag vX.Y.Z
git push origin vX.Y.Z
git tag -f latest # move the floating tag to this commit
git push origin latest --forcevX.Y.Z tags are permanent and never move. latest always points at the newest one — that's the only tag ever force-pushed.
License
Apache-2.0. See LICENSE and NOTICE for third-party dependency/service attribution (Hypernode Brancher API, system ssh/rsync, MCP Python SDK).
Available Tools
7 toolsbrancher_appsA
List every Hypernode <appname> with a configured API token.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It clearly indicates this is a read-only listing operation, but it does not disclose any potential edge cases (e.g., output size, pagination, or error behavior). The mention of 'every' suggests comprehensiveness, but no additional behavioral traits are described.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence that precisely conveys the tool's purpose without any redundant information. It is perfectly front-loaded and easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple listing tool with no parameters and an output schema available, the description is complete. It specifies exactly what is listed (Hypernode app names) and the filtering condition (with a configured API token). No further details are necessary.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is nothing for the description to clarify. The baseline score of 4 applies, and the description correctly avoids any unnecessary parameter details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (List), the resource (Hypernode appname), and a specific condition (with a configured API token). It effectively distinguishes from sibling tools like brancher_list by specifying the token requirement.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use this tool—when you need to list Hypernode apps that have API tokens. It does not explicitly mention alternatives or exclusions, but the purpose is self-evident enough for basic selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
brancher_createC
Create a Brancher node, wait for it, sanitize it, and report it ready.
| Name | Required | Description | Default |
|---|---|---|---|
| labels | Yes | ||
| appname | Yes | ||
| clear_services | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must fully disclose behavioral traits. It mentions waiting, sanitizing, and reporting, hinting at a non-instant operation, but fails to explain what 'sanitize' means, whether it's destructive, what permissions are needed, or what 'report it ready' entails. The description is too vague to make the tool's behavior predictable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence, which is concise in length, but it packs multiple actions without clear separation or explanation. It is not well-structured for quick comprehension of the tool's purpose and behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 3 parameters (2 required), no schema descriptions, and an output schema (content unknown), the description is severely incomplete. It does not explain the parameters, the return value, or the actual behavior beyond vague steps. The agent cannot reliably invoke this tool based on the description alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description does not mention any of the three parameters (appname, labels, clear_services). The description adds no meaning beyond the schema, leaving the agent without any guidance on how to populate the inputs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Create' and the resource 'Brancher node', distinguishing it from sibling tools like list, delete, exec, put, and ssh_info. It adds procedural steps (wait, sanitize, report ready) which, while vague, still clarify the tool's multi-step nature.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives, nor any prerequisites, exclusions, or context. The description only states what it does, not when it should be chosen.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
brancher_deleteA
Delete a Brancher node, gated behind a confirm=True re-call.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | ||
| node_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full behavioral disclosure. It reveals that deletion is not immediate but requires a second call with confirm=True, which is a critical behavioral trait. However, it does not elaborate on what happens on the first call (e.g., no-op or preview) or whether deletion is reversible, which keeps it from being a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence that front-loads the core action ('Delete a Brancher node') and immediately follows with the critical behavioral constraint. Every word earns its place; there is no redundancy or unnecessary information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity (2 parameters, no nested objects) and the presence of an output schema, the description is nearly adequate but lacks clarity on what the first call (without confirm=True) does. This omission could confuse an agent about the tool's behavior. The description is otherwise sufficient for the basic delete operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It only partially addresses the confirm parameter by explaining its role in the gating mechanism. The node_name parameter is not described at all. This leaves a significant gap for the required parameter, limiting the agent's ability to correctly invoke the tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Delete a Brancher node') with a specific verb and resource. It also distinguishes from sibling tools (brancher_create, brancher_list, etc.) by implying deletion rather than creation, listing, or execution. The mention of the confirmation gating adds specificity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is used when a node needs to be deleted, but it does not provide explicit guidance on when to use it versus alternatives (e.g., when not to delete, or that brancher_create might be needed to recreate). No exclusions or alternative tools are mentioned, leaving the agent to infer context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
brancher_execA
Execute command on a Brancher node over SSH; return stdout/stderr/exit_code.
| Name | Required | Description | Default |
|---|---|---|---|
| command | Yes | ||
| timeout | No | ||
| node_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description effectively discloses the tool's behavior: it executes a command via SSH on a specific node and returns standard output, error, and exit code. It implicitly informs the agent that this is a potentially impactful action (remote command execution) and that it requires SSH access, which is transparent enough.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise, just one sentence with 11 words. It front-loads the main action and return value, leaving no wasted words. Every element (execute, command, SSH node, return) is necessary and adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a relatively simple tool with a clear action and an output schema (implied return of stdout/stderr/exit_code), the description covers the essential purpose and behavior. It does not specify failure modes or SSH configuration requirements, but given the context (no nested objects, few parameters) and the presence of an output schema, it is sufficiently complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema description coverage is 0%, the description briefly adds context by naming the two required parameters (command, node_name) within its purpose. However, it does not explain the optional timeout parameter (default 30 seconds) or provide details on valid formats or constraints for the parameters beyond what is in the schema. Given low coverage, the description compensates somewhat.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (Execute over SSH), the target (Brancher node), and the return values (stdout/stderr/exit_code). It effectively distinguishes from sibling tools like brancher_list, brancher_put, etc., which are about managing files or listing, not executing commands.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not provide any guidance on when or when not to use this tool versus alternatives. Since there are siblings like brancher_ssh_info which might provide connection info, but no instructions on when to prefer one over the other or any prerequisites (e.g., SSH setup) are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
brancher_listB
List active Brancher nodes for appname.
| Name | Required | Description | Default |
|---|---|---|---|
| appname | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full responsibility for behavioral disclosure. 'List active Brancher nodes' suggests a read-only operation, but does not clarify if the list is paginated, limited, or includes metadata (e.g., status, uptime). The description minimally conveys safety (read-only) but omits specifics like authentication needs or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise at just one line with no wasted words. It appropriately front-loads the action and target resource, making it easy for an AI agent to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is only one parameter and an output schema exists, the description is somewhat complete for a simple listing tool. However, it lacks details on what the list contains (e.g., node IDs, IPs, status) and does not clarify if the tool returns only active nodes or all nodes filtered by activity. With no annotations, more context on behavior would be valuable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema describes only one parameter (`appname`) with 0% schema description coverage, meaning the description must add meaning. However, the description only mentions `appname` in context without elaborating on its format, acceptable values, or examples. It merely restates that `appname` is needed, adding little beyond the schema itself.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (list) and the resource (active Brancher nodes), and it specifies the required parameter `appname`. However, it does not differentiate from sibling tools like `brancher_ssh_info` or `brancher_create` in terms of what makes this specific listing distinct.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by requiring `appname`, but provides no explicit guidance on when to use this tool versus alternatives (e.g., `brancher_ssh_info` for SSH info or `brancher_delete` for deletion). There is no mention of prerequisites or conditions for using the list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
brancher_putB
Sync local_path to remote_path on a Brancher node via rsync.
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | ||
| node_name | Yes | ||
| local_path | Yes | ||
| remote_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full responsibility for behavioral disclosure. It only mentions 'via rsync', but does not disclose overwrite behavior, directory creation, error handling, or any side effects. The agent is left guessing about important safety-relevant behaviors.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no fluff or repetition. It is front-loaded and efficient, containing exactly the core information without wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having an output schema (content unknown), the description fails to address many aspects relevant to a file sync tool: return values, error conditions, whether directories are created, handling of existing files, permission requirements, or rsync flags. The brevity leaves significant gaps for practical usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% — none of the parameters have descriptions in the schema. The tool description merely restates the role of local_path and remote_path ('sync local_path to remote_path') but does not clarify their format, constraints, or the purpose of node_name and port. The linking of path parameters is the only semantic addition.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('sync'), the source ('local_path'), destination ('remote_path'), the mechanism ('via rsync'), and the target ('on a Brancher node'). This distinguishes it from sibling tools like brancher_list, brancher_delete, and brancher_exec, which serve different purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives, no prerequisites, and no exclusions. For example, it doesn't mention when to use brancher_put instead of brancher_exec for file transfer, or if there are size or permission limitations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
brancher_ssh_infoC
Return SSH connection details (host, user, port) for a Brancher node.
| Name | Required | Description | Default |
|---|---|---|---|
| node_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description bears full responsibility for behavioral disclosure. It only states the return value, omitting whether the operation is read-only, requires authentication, what happens if the node does not exist, or any error conditions. This is insufficient for safe invocation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no wasted words. However, it is too brief to cover necessary details, making it merely adequate rather than excellent. It earns its place but misses opportunities to add value without much extra length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple info retrieval tool with an existing output schema, the description covers the essential return fields (host, user, port). However, it does not address error scenarios, preconditions (node existence), or side effects. Annotations are absent, leaving behavioral gaps. Completeness is acceptable but not thorough.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage for the required node_name parameter. The description adds only 'for a Brancher node', implying node_name identifies a node but failing to explain valid values, case sensitivity, or where to obtain the name. It does not compensate for the schema's lack of documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns SSH connection details (host, user, port) for a Brancher node, which is a specific verb and resource. It differentiates well from siblings like brancher_list (listing) or brancher_exec (executing commands), leaving no ambiguity about this tool's role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives (e.g., use it after listing nodes to get connection info, or before executing SSH commands). No when-not-to-use or exclusion criteria are mentioned, leaving the agent to infer context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
1 tool update
- Added
brancher_apps
6 tool updates
v0.1.0- First observed
brancher_create - First observed
brancher_delete - First observed
brancher_exec - First observed
brancher_list - First observed
brancher_put - First observed
brancher_ssh_info
TDQS
Each tool serves a unique purpose: ssh_info retrieves connection details, list enumerates nodes, delete removes a node, exec runs commands, put syncs files, create provisions a node, and apps lists configured apps. There is no functional overlap or ambiguity.
All tools share the 'brancher_' prefix, but the naming pattern is inconsistent: most use verb-noun (list, delete, exec, put, create) while two are noun-only (ssh_info, apps). This creates minor inconsistency in verb usage and clarity.
Seven tools is a reasonable number for managing Brancher nodes—covering core CRUD operations plus execution, file sync, and SSH info. It is neither sparse nor overwhelming for the domain.
The tool surface covers the full lifecycle of a node: create, list, delete, execute commands, sync files, retrieve SSH details, and list apps. No essential operation appears missing for the stated purpose of managing Brancher nodes.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Plan Salesforce deploys, open pull requests and trigger pipelines from your AI client.
Connect AI assistants to GitHub - manage repos, issues, PRs, and workflows through natural language.
- mcp-serverOAuthcom.make
Give your AI agents the tools to build, manage, and run automation workflows.
- mcpOAuthcom.vibgrate
Query your team's drift, vulnerability, and upgrade data from any AI assistant. OAuth 2.1, 51 tools.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables AI assistants to automate DDEV development environments, including project management, database operations, and executing commands for various CMS frameworks.143913GPL 2.0
- FlicenseBqualityCmaintenanceEnables deploying sites, managing databases, and troubleshooting deployments on Hostwares from AI assistants.14-
- AlicenseAqualityCmaintenanceEnables AI agents to interact with Adobe Commerce Cloud projects via REST API and SSH for database queries, log reading, environment management, and more, with no PHP CLI required.1579MIT
- FlicenseNot gradedqualityBmaintenanceEnables AI assistants to start, manage, and embed live application previews in iframes, with support for multiple frameworks, Docker, tunnels, and authentication.-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/ProxiBlue/pb-hypernode-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server