Make MCPHub deployments deterministic
This commit is contained in:
@@ -1,102 +1,184 @@
|
|||||||
---
|
---
|
||||||
name: mcphub-deployer
|
name: mcphub-deployer
|
||||||
description: Install, update, publish, test, and remove MCP servers through the CasaDeRoll MCPHub on Unraid. Use for requests to add an MCP from a catalog, GitHub, npm, PyPI, or local source; move a portable MCP into MCPHub; expose a new /mcp/NAME route; register it in Hermes or OpenWebUI; or repair an MCPHub deployment.
|
description: Install, update, disable, test, publish, or remove portable MCP servers in CasaDeRoll MCPHub on Unraid. Use for MCP catalog, GitHub, npm, PyPI, Go-binary, existing HTTP-MCP, client-registration, MCPHub repair, or moving an MCP out of Athena or Hermes.
|
||||||
---
|
---
|
||||||
|
|
||||||
# MCPHub Deployer
|
# MCPHub Deployer
|
||||||
|
|
||||||
Treat MCPHub on Unraid as the production home for portable MCP servers. Do not
|
Install portable MCPs in the existing `MCPHub` container on Unraid. Never
|
||||||
create another MCP container on Athena merely because an upstream project ships
|
create one Docker container per portable MCP and never install one inside
|
||||||
a Docker image. Do not install or launch a portable stdio MCP inside Hermes;
|
Hermes. Hermes, OpenWebUI, Pi, and other agents are clients of MCPHub.
|
||||||
Hermes is a client of the separately managed MCPHub routes.
|
|
||||||
|
|
||||||
## Production facts
|
## Fixed production map
|
||||||
|
|
||||||
- Container: `MCPHub` on Unraid (`192.168.1.2`).
|
Use these paths directly. Do not search the filesystem for alternatives.
|
||||||
- Image: `casaderoll/mcphub:<version>`, based on `samanhappy/mcphub`.
|
|
||||||
- Appdata: `/mnt/nvme-storage/appdata/MCPHub`.
|
|
||||||
- Secrets: `/mnt/nvme-storage/appdata/MCPHub/secrets/*.env`, mode `0600`.
|
|
||||||
- Client token: `/mnt/nvme-storage/appdata/MCPHub/client-token`.
|
|
||||||
- UI and MCP base: `http://192.168.1.2:8787`.
|
|
||||||
- Each server stays separately addressable as `/mcp/<name>`.
|
|
||||||
- Versioned sources live in the `AI-Profile-Router` repository.
|
|
||||||
|
|
||||||
Use the `unraid` MCP for live inspection and deployment. Use Git tools or the
|
- Host: Unraid `192.168.1.2`
|
||||||
documented repository workflow for durable source changes. If no authorized
|
- Container: `MCPHub`
|
||||||
write path to the repository exists, stop after preparing a patch and report
|
- UI/base URL: `http://192.168.1.2:8787`
|
||||||
that exact blocker; never make an unversioned production-only implementation.
|
- Operational source/build tree: `/mnt/nvme-storage/appdata/MCPHub/build`
|
||||||
|
- Dockerfile: `platform/mcphub/Dockerfile` below that tree
|
||||||
|
- Server declaration: `platform/mcphub/configure-settings.py`
|
||||||
|
- Client registry: `config/mcp-registry.json`
|
||||||
|
- Unraid template: `config/unraid-templates/my-MCPHub.xml`
|
||||||
|
- Persistent state: `/mnt/nvme-storage/appdata/MCPHub`
|
||||||
|
- Secrets: `/mnt/nvme-storage/appdata/MCPHub/secrets/<server>.env`, mode `0600`
|
||||||
|
- Client bearer token: `/mnt/nvme-storage/appdata/MCPHub/client-token`
|
||||||
|
- Individual route: `http://192.168.1.2:8787/mcp/<server>`
|
||||||
|
|
||||||
## Choose the integration type
|
The operational build tree is persistent and covered by the normal Unraid
|
||||||
|
Appdata backup. The checkout below is legacy and MUST NOT be used or inspected
|
||||||
|
for MCPHub work:
|
||||||
|
|
||||||
1. **Existing HTTP MCP:** Register its URL and optional auth header. Do not copy
|
`/mnt/nvme-storage/Eigene Dateien/Michael/Entwicklung/AI-Profile-Router`
|
||||||
its code or create a duplicate backend.
|
|
||||||
2. **Packaged stdio MCP:** Run a pinned npm or Python package inside MCPHub.
|
|
||||||
Prefer `npx <package>@<version>` or `uvx --from <package>==<version>` only
|
|
||||||
after verifying the real executable and transport.
|
|
||||||
3. **Custom MCP:** Keep its source in the repository, copy it into the MCPHub
|
|
||||||
image, pin its dependencies, and register its stdio command.
|
|
||||||
4. **Host-bound administration:** Keep it outside MCPHub only when it truly
|
|
||||||
requires a host-local socket, filesystem, or hardware device. Prefer SSH or
|
|
||||||
an authenticated HTTP endpoint from MCPHub over another permanent manager.
|
|
||||||
|
|
||||||
## Durable source of truth
|
The normal Git repository remains the durable documentation/history. Publish
|
||||||
|
the same focused files there when an authorized Git write path is available.
|
||||||
|
Lack of Git access is a warning to report, not permission to search for other
|
||||||
|
checkouts and not a reason to abandon an otherwise requested local install.
|
||||||
|
|
||||||
Change only the files required for the selected integration:
|
## Mandatory fast path
|
||||||
|
|
||||||
- `platform/mcphub/Dockerfile` for packages, binaries, or copied custom code.
|
For a normal installation, perform these phases once and in order. Do not
|
||||||
- `platform/mcphub/configure-settings.py` for the declared MCPHub server entry.
|
restart discovery after a phase has completed.
|
||||||
- The MCP source under its existing versioned directory.
|
|
||||||
- `config/mcp-registry.json` for client-visible metadata and routing.
|
|
||||||
- `config/unraid-templates/my-MCPHub.xml` when the image tag, mounts, or
|
|
||||||
environment must change.
|
|
||||||
- A focused test or probe when the existing verifier cannot cover the server.
|
|
||||||
|
|
||||||
Do not treat a manual edit of `mcp_settings.json` as the final change:
|
### 1. Preflight — at most six checks
|
||||||
`configure-settings.py` regenerates `mcpServers` when the container starts.
|
|
||||||
Preserve existing users, bearer keys, prompts, resources, and tool toggles.
|
|
||||||
|
|
||||||
## Workflow
|
Check only:
|
||||||
|
|
||||||
1. Inspect the current MCPHub container, declared servers, target backend, and
|
1. `MCPHub` container state, image tag, mounts, and network.
|
||||||
existing service catalog. Reuse an existing service instead of installing a
|
2. The four fixed production files listed above.
|
||||||
second copy.
|
3. Existing MCPHub server names to avoid duplication.
|
||||||
2. Inspect the upstream repository and release. Verify license, maintained
|
4. Target service reachability or the upstream release.
|
||||||
version, actual command, transport, tool schemas, required credentials, and
|
5. Required secret-file presence; never print its values.
|
||||||
whether it needs outbound network access. Do not infer an API from a README
|
6. Current Git availability, if any.
|
||||||
alone when source routes or a live probe are available.
|
|
||||||
3. State a short plan and rollback. If the user asked only for a plan, stop
|
Never run a filesystem-wide `find`. Never read unrelated Compose stacks,
|
||||||
before changing production. Otherwise continue under the granted change.
|
repositories, documentation trees, or all container logs.
|
||||||
4. Implement the smallest versioned change. Pin package and base-image versions;
|
|
||||||
never introduce an unpinned production `latest`, `npx -y`, or floating Git
|
### 2. Classify once
|
||||||
branch merely for convenience.
|
|
||||||
5. Place real credentials only in the matching Unraid secret env file. Never
|
Choose exactly one integration:
|
||||||
commit, print, or return them in tool output.
|
|
||||||
6. Build a new local MCPHub image tag and update the Unraid template to that
|
- Existing HTTP MCP: declare its URL and authentication; do not copy it.
|
||||||
exact tag. Do not overwrite the running tag before the image builds cleanly.
|
- Packaged stdio MCP: pin and install the exact npm/Python package in MCPHub.
|
||||||
7. Recreate only `MCPHub` through DockerMan so it remains a managed Unraid
|
- Released binary: pin version and checksum; download and verify it during the
|
||||||
container. Preserve `/mnt/nvme-storage/appdata/MCPHub`. Do not restart
|
Docker image build. Do not commit a downloaded binary.
|
||||||
Athena, Router, Qwen, Hermes, OpenWebUI, WireGuard, or unrelated containers.
|
- Custom MCP: keep source in the build tree and copy it into the image.
|
||||||
8. Verify container health, an MCP handshake, `list_tools`, schema compatibility,
|
- Host-bound MCP: leave it on its required host and proxy its authenticated
|
||||||
and one bounded read-only call. A running container alone is not success.
|
HTTP endpoint through MCPHub.
|
||||||
9. Register `http://192.168.1.2:8787/mcp/<name>` in every intended Hermes
|
|
||||||
profile and in OpenWebUI through the declared client registry. New downstream
|
Do not reconsider this classification unless a real build or handshake result
|
||||||
MCPs are not automatically advertised to clients. Reload only the affected
|
contradicts it.
|
||||||
profile gateway if discovery requires it, then test from the real client.
|
|
||||||
10. Commit and push only the intended files. Confirm the normal Unraid Appdata
|
### 3. Interpret the user's intent
|
||||||
backup includes MCPHub; do not build a separate recovery bundle.
|
|
||||||
|
- “Prüfe/plane/zeige den Ablauf”: inspect and return a short plan; change
|
||||||
|
nothing.
|
||||||
|
- “Installiere/baue ein/los/Abfahrt”: continue through deployment and tests.
|
||||||
|
- “Zunächst deaktiviert”: install the runtime and declaration with
|
||||||
|
`enabled: false`; do not add it to client registries yet.
|
||||||
|
- “Nur lesen”: disable or omit mutating tools before client publication.
|
||||||
|
|
||||||
|
Ask only for information that cannot be derived safely: credentials, a
|
||||||
|
material license decision, or an ambiguous destructive permission.
|
||||||
|
|
||||||
|
### 4. Implement the smallest change
|
||||||
|
|
||||||
|
Modify only the necessary fixed production files. Rules:
|
||||||
|
|
||||||
|
- Pin image, package, release, and checksum versions.
|
||||||
|
- Put credentials only in the matching secret file with mode `0600`.
|
||||||
|
- Never print, log, commit, summarize, or return a secret.
|
||||||
|
- Use `/usr/local/bin/run-with-env` for secret-backed stdio servers.
|
||||||
|
- Declare servers in `configure-settings.py`; do not manually treat
|
||||||
|
`mcp_settings.json` as the source of truth.
|
||||||
|
- Preserve existing users, bearer keys, prompts, resources, enabled states,
|
||||||
|
and per-tool toggles.
|
||||||
|
- Build a new image tag. Never overwrite the tag currently running.
|
||||||
|
- Update the Unraid template to the exact new tag.
|
||||||
|
|
||||||
|
For servers exposing many tools, install disabled first. After a successful
|
||||||
|
local test, enable only the required tool groups in MCPHub. Do not publish an
|
||||||
|
unfiltered large server to clients.
|
||||||
|
|
||||||
|
### 5. Deploy without collateral changes
|
||||||
|
|
||||||
|
Build from `/mnt/nvme-storage/appdata/MCPHub/build`, then recreate only
|
||||||
|
`MCPHub` through Unraid DockerMan so it stays a managed Unraid container.
|
||||||
|
Preserve all Appdata and mounts.
|
||||||
|
|
||||||
|
Never restart Athena, Router, Qwen, Hermes, OpenWebUI, WireGuard, Unraid, or
|
||||||
|
unrelated containers for an MCPHub deployment.
|
||||||
|
|
||||||
|
### 6. Prove the result
|
||||||
|
|
||||||
|
Verify, in this order:
|
||||||
|
|
||||||
|
1. New container uses the intended image and remains healthy.
|
||||||
|
2. Existing MCP routes still handshake.
|
||||||
|
3. New server starts when enabled.
|
||||||
|
4. MCP handshake and `list_tools` succeed with valid schemas.
|
||||||
|
5. One bounded read-only function returns plausible live data.
|
||||||
|
6. No test download, queue item, write, or second backend remains.
|
||||||
|
7. If installed disabled, return it to disabled after the temporary test.
|
||||||
|
|
||||||
|
A running container alone is not success. Never claim install, test,
|
||||||
|
registration, Git push, or backup without observing its result.
|
||||||
|
|
||||||
|
### 7. Publish to clients only after filtering
|
||||||
|
|
||||||
|
Add `http://192.168.1.2:8787/mcp/<server>` to
|
||||||
|
`config/mcp-registry.json` only after the server and selected tools have passed
|
||||||
|
verification. Generate intended Hermes/OpenWebUI registrations from that one
|
||||||
|
registry. Reload only the affected client gateway if required.
|
||||||
|
|
||||||
|
New MCPHub servers are not automatically advertised by the model router.
|
||||||
|
|
||||||
|
### 8. Finish compactly
|
||||||
|
|
||||||
|
Report exactly:
|
||||||
|
|
||||||
|
- installed version and image tag;
|
||||||
|
- enabled/disabled state and exposed tool count;
|
||||||
|
- secret-file path without values;
|
||||||
|
- handshake and read-only probe result;
|
||||||
|
- client registrations changed or intentionally omitted;
|
||||||
|
- Git status/push result;
|
||||||
|
- rollback image tag.
|
||||||
|
|
||||||
|
Do not narrate repeated planning or internal reconsideration.
|
||||||
|
|
||||||
|
## Context-compaction checkpoint
|
||||||
|
|
||||||
|
Before a long build or whenever context use approaches compression, write a
|
||||||
|
small checkpoint to:
|
||||||
|
|
||||||
|
`/mnt/nvme-storage/appdata/MCPHub/work/<server>.json`
|
||||||
|
|
||||||
|
Store only: requested outcome, integration type, completed phases, modified
|
||||||
|
paths, old/new image tags, pending action, verification results, and rollback.
|
||||||
|
Never store credentials. After compression, reread this SKILL.md from the fixed
|
||||||
|
Hermes skill path plus that checkpoint, then continue at the pending phase.
|
||||||
|
Never rediscover completed phases.
|
||||||
|
|
||||||
|
Delete the checkpoint after a successful final report. Keep it on failure so a
|
||||||
|
new session can resume safely.
|
||||||
|
|
||||||
|
## Hard limits and stop rules
|
||||||
|
|
||||||
|
- Maximum two attempts for the same command, endpoint, or hypothesis.
|
||||||
|
- Maximum one corrected build after the first failed build.
|
||||||
|
- Never repeat “I now understand the mechanism” and continue researching.
|
||||||
|
- If upstream command, transport, license, or credentials remain unknown after
|
||||||
|
two focused checks, stop and state that exact blocker.
|
||||||
|
- If deployment fails, keep the previous container/image running and report the
|
||||||
|
failing phase. Do not improvise a second container or unversioned binary.
|
||||||
|
- Ask before destructive queue actions, downloads, service mutations, or
|
||||||
|
credential rotation that the user did not explicitly authorize.
|
||||||
|
|
||||||
## Rollback
|
## Rollback
|
||||||
|
|
||||||
Restore the previous image tag and declarative server list, recreate only
|
Restore the previous image tag and declarative server entry, recreate only
|
||||||
`MCPHub`, and repeat handshake plus one read-only probe. Do not delete Appdata
|
`MCPHub`, and repeat existing-route handshakes plus one read-only probe. Never
|
||||||
or secret files during rollback. Remove a secret only after confirming no
|
delete Appdata or shared secret files during rollback.
|
||||||
remaining server uses it.
|
|
||||||
|
|
||||||
## Stop conditions
|
|
||||||
|
|
||||||
- Stop after one corrected attempt when the upstream command, API, transport,
|
|
||||||
or repository write path remains unknown.
|
|
||||||
- Never fake tool results or claim a deploy, client registration, commit, push,
|
|
||||||
or backup succeeded without its actual result.
|
|
||||||
- Ask before any destructive queue action, download, service mutation, or
|
|
||||||
credential rotation that was not explicitly requested.
|
|
||||||
|
|||||||
Reference in New Issue
Block a user