Files
mcpctl/templates/unifi-network.yaml

43 lines
1.9 KiB
YAML
Raw Permalink Normal View History

name: unifi-network
fix(templates): make the shipped templates match reality The templates are what `create server --from-template` builds from and what mcpd seeds on start, so drift there ships broken servers. Nothing ever read these files in a test, and they had rotted badly. - grafana: GRAFANA_URL now defaults to the in-cluster ClusterIP and the description spells out why the public hostname is wrong — reaching a co-located Grafana over its ingress hairpins through the per-host Envoy L7 policy, which drops the caller's identity and returns a bare `Access denied` 403 with a perfectly valid token. That cost a day of looking at the token. - unifi-network: was wrong on every field that mattered. `runtime: python` for an npm package, an env contract (UNIFI_HOST/USERNAME/PASSWORD) the package doesn't read, and no probe. Now UNIFI_TARGETS with the classic-vs-unifi_os distinction and the :8443 egress caveat written down. - docmost, gitea: both carried "health check disabled" comments citing a limitation of the old docker-exec probe, which readiness-via-proxy removed. Both probes verified against the live servers. gitea uses search_repos, not get_me, because get_me needs a `read:user` scope a repo-scoped token lacks. - filesystem: packageName was `@anthropic/filesystem-mcp`, which 404s on npm — the template could never have installed. Points at the real package. - terraform: deleted. `@anthropic/terraform-mcp` 404s too and there is no npm-published replacement to point it at. - node-red: deleted, the service is gone. Two supporting fixes: - The seeder declared no `runtime` field and never wrote the column, so a template asking for the python runner silently seeded as null and got node. - A new templates test reads every shipped file: schema-valid, a runner the orchestrator knows, some way to actually start, unique env names, and a readiness probe (without one an instance can only ever report `live`). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0114dg56YmVacyqhp5fitcTb
2026-08-09 23:53:22 +01:00
version: "2.0.0"
description: UniFi Network MCP server for managing UniFi network devices, clients, and configuration
packageName: "unifi-network-mcp"
fix(templates): make the shipped templates match reality The templates are what `create server --from-template` builds from and what mcpd seeds on start, so drift there ships broken servers. Nothing ever read these files in a test, and they had rotted badly. - grafana: GRAFANA_URL now defaults to the in-cluster ClusterIP and the description spells out why the public hostname is wrong — reaching a co-located Grafana over its ingress hairpins through the per-host Envoy L7 policy, which drops the caller's identity and returns a bare `Access denied` 403 with a perfectly valid token. That cost a day of looking at the token. - unifi-network: was wrong on every field that mattered. `runtime: python` for an npm package, an env contract (UNIFI_HOST/USERNAME/PASSWORD) the package doesn't read, and no probe. Now UNIFI_TARGETS with the classic-vs-unifi_os distinction and the :8443 egress caveat written down. - docmost, gitea: both carried "health check disabled" comments citing a limitation of the old docker-exec probe, which readiness-via-proxy removed. Both probes verified against the live servers. gitea uses search_repos, not get_me, because get_me needs a `read:user` scope a repo-scoped token lacks. - filesystem: packageName was `@anthropic/filesystem-mcp`, which 404s on npm — the template could never have installed. Points at the real package. - terraform: deleted. `@anthropic/terraform-mcp` 404s too and there is no npm-published replacement to point it at. - node-red: deleted, the service is gone. Two supporting fixes: - The seeder declared no `runtime` field and never wrote the column, so a template asking for the python runner silently seeded as null and got node. - A new templates test reads every shipped file: schema-valid, a runner the orchestrator knows, some way to actually start, unique env names, and a readiness probe (without one an instance can only ever report `live`). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0114dg56YmVacyqhp5fitcTb
2026-08-09 23:53:22 +01:00
runtime: node
transport: STDIO
repositoryUrl: https://github.com/sirkirby/unifi-mcp
fix(templates): make the shipped templates match reality The templates are what `create server --from-template` builds from and what mcpd seeds on start, so drift there ships broken servers. Nothing ever read these files in a test, and they had rotted badly. - grafana: GRAFANA_URL now defaults to the in-cluster ClusterIP and the description spells out why the public hostname is wrong — reaching a co-located Grafana over its ingress hairpins through the per-host Envoy L7 policy, which drops the caller's identity and returns a bare `Access denied` 403 with a perfectly valid token. That cost a day of looking at the token. - unifi-network: was wrong on every field that mattered. `runtime: python` for an npm package, an env contract (UNIFI_HOST/USERNAME/PASSWORD) the package doesn't read, and no probe. Now UNIFI_TARGETS with the classic-vs-unifi_os distinction and the :8443 egress caveat written down. - docmost, gitea: both carried "health check disabled" comments citing a limitation of the old docker-exec probe, which readiness-via-proxy removed. Both probes verified against the live servers. gitea uses search_repos, not get_me, because get_me needs a `read:user` scope a repo-scoped token lacks. - filesystem: packageName was `@anthropic/filesystem-mcp`, which 404s on npm — the template could never have installed. Points at the real package. - terraform: deleted. `@anthropic/terraform-mcp` 404s too and there is no npm-published replacement to point it at. - node-red: deleted, the service is gone. Two supporting fixes: - The seeder declared no `runtime` field and never wrote the column, so a template asking for the python runner silently seeded as null and got node. - A new templates test reads every shipped file: schema-valid, a runner the orchestrator knows, some way to actually start, unique env names, and a readiness probe (without one an instance can only ever report `live`). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0114dg56YmVacyqhp5fitcTb
2026-08-09 23:53:22 +01:00
healthCheck:
# list_sites calls the controller (/api/self/sites), so a pass proves the
# whole path: egress to the controller port, TLS, login, session. The old
# template disabled the probe entirely on the belief that STDIO probes only
# worked for npm packages — that stopped being true once readiness probes
# started going through the MCP proxy, and the gap let this server sit at
# "healthy" for months without ever reaching the controller.
tool: list_sites
arguments: {}
intervalSeconds: 60
timeoutSeconds: 15
env:
fix(templates): make the shipped templates match reality The templates are what `create server --from-template` builds from and what mcpd seeds on start, so drift there ships broken servers. Nothing ever read these files in a test, and they had rotted badly. - grafana: GRAFANA_URL now defaults to the in-cluster ClusterIP and the description spells out why the public hostname is wrong — reaching a co-located Grafana over its ingress hairpins through the per-host Envoy L7 policy, which drops the caller's identity and returns a bare `Access denied` 403 with a perfectly valid token. That cost a day of looking at the token. - unifi-network: was wrong on every field that mattered. `runtime: python` for an npm package, an env contract (UNIFI_HOST/USERNAME/PASSWORD) the package doesn't read, and no probe. Now UNIFI_TARGETS with the classic-vs-unifi_os distinction and the :8443 egress caveat written down. - docmost, gitea: both carried "health check disabled" comments citing a limitation of the old docker-exec probe, which readiness-via-proxy removed. Both probes verified against the live servers. gitea uses search_repos, not get_me, because get_me needs a `read:user` scope a repo-scoped token lacks. - filesystem: packageName was `@anthropic/filesystem-mcp`, which 404s on npm — the template could never have installed. Points at the real package. - terraform: deleted. `@anthropic/terraform-mcp` 404s too and there is no npm-published replacement to point it at. - node-red: deleted, the service is gone. Two supporting fixes: - The seeder declared no `runtime` field and never wrote the column, so a template asking for the python runner silently seeded as null and got node. - A new templates test reads every shipped file: schema-valid, a runner the orchestrator knows, some way to actually start, unique env names, and a readiness probe (without one an instance can only ever report `live`). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0114dg56YmVacyqhp5fitcTb
2026-08-09 23:53:22 +01:00
- name: UNIFI_TARGETS
description: >-
JSON array of controllers. One object per controller:
{"id", "base_url", "controller_type", "default_site", "auth":
{"username","password"}, "verify_ssl"}.
controller_type is "classic" for a self-hosted UniFi Network controller
(login /api/login, no path prefix) or "unifi_os" for a UDM/UniFi OS
console (login /api/auth/login, API under /proxy/network). Choosing the
wrong one sends every request to a path that 404s while the server still
starts cleanly.
base_url must carry the real controller port — a self-hosted controller
is usually :8443, and :443 on the same host is often an unrelated
service. Note that MCP server pods only egress 80/443 by default, so any
other port needs an explicit NetworkPolicy (Pulumi
`mcpctl.serverEgressTargets`).
required: true
fix(templates): make the shipped templates match reality The templates are what `create server --from-template` builds from and what mcpd seeds on start, so drift there ships broken servers. Nothing ever read these files in a test, and they had rotted badly. - grafana: GRAFANA_URL now defaults to the in-cluster ClusterIP and the description spells out why the public hostname is wrong — reaching a co-located Grafana over its ingress hairpins through the per-host Envoy L7 policy, which drops the caller's identity and returns a bare `Access denied` 403 with a perfectly valid token. That cost a day of looking at the token. - unifi-network: was wrong on every field that mattered. `runtime: python` for an npm package, an env contract (UNIFI_HOST/USERNAME/PASSWORD) the package doesn't read, and no probe. Now UNIFI_TARGETS with the classic-vs-unifi_os distinction and the :8443 egress caveat written down. - docmost, gitea: both carried "health check disabled" comments citing a limitation of the old docker-exec probe, which readiness-via-proxy removed. Both probes verified against the live servers. gitea uses search_repos, not get_me, because get_me needs a `read:user` scope a repo-scoped token lacks. - filesystem: packageName was `@anthropic/filesystem-mcp`, which 404s on npm — the template could never have installed. Points at the real package. - terraform: deleted. `@anthropic/terraform-mcp` 404s too and there is no npm-published replacement to point it at. - node-red: deleted, the service is gone. Two supporting fixes: - The seeder declared no `runtime` field and never wrote the column, so a template asking for the python runner silently seeded as null and got node. - A new templates test reads every shipped file: schema-valid, a runner the orchestrator knows, some way to actually start, unique env names, and a readiness probe (without one an instance can only ever report `live`). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0114dg56YmVacyqhp5fitcTb
2026-08-09 23:53:22 +01:00
defaultValue: >-
[{"id": "home", "base_url": "https://unifi.example.com:8443",
"controller_type": "classic", "default_site": "default",
"auth": {"username": "CHANGE_ME", "password": "CHANGE_ME"},
"verify_ssl": false}]