Upload and review a package
Bring a single Python stdio MCP server or a supported single-image OCI or Docker archive. The author uploads an immutable package, an administrator reviews its original bytes and an explicit deployment makes its tools callable.
Upload an MCP package
Select Upload in the managed Hub dock and enter your own token. Enter a short package name and select Python stdio source or Docker / OCI image archive. The browser computes the digest locally and uploads the selected file only on Upload package. The bytes are executable material. Have the administrator review the package before approving it. Approval adds it to the deployment profile selector. Upload, approval and deployment are three separate actions.
For the following shell examples, define the authenticated curl helper with your named caller credential. Authenticated curl setup
Compute SHA-256 over the exact file bytes, then send a raw binary request body. The Text stats example supplies a standalone Python server and its reviewed tool schema. Python uploads allow up to 256 KiB. Docker/OCI TAR archives allow up to 32 MiB with format=oci. An owner may store at most 16 packages and 64 MiB. The installation cap is 128 packages and 256 MiB. A mismatched digest or rejected upload must be fixed before approval.
PACKAGE_FILE=examples/text-stats/server.py
DIGEST=$(python3 -c 'import hashlib,sys; print(hashlib.sha256(open(sys.argv[1],"rb").read()).hexdigest())' "$PACKAGE_FILE")
hub -H 'Content-Type: application/octet-stream' --data-binary "@$PACKAGE_FILE" "$HUB_URL/api/v1/packages?format=python&name=demo&digest=sha256:$DIGEST"
hub "$HUB_URL/api/v1/packages"
OCI image requirements
The OCI archive must contain a single Linux amd64 or arm64 image for the worker host. It needs executable /app/mcp, /bin/sleep, /usr/bin/timeout and /usr/bin/flock, together with their runtime libraries. The MCP process must speak newline-delimited stdio and advertise the reviewed tools. Review the helper executables as well as the MCP server. The hub normalizes image configuration and checks extracted contents. The archive and its metadata are encrypted in the package registry. The normalized image layers imported after approval remain in the local Docker image store after an instance is removed. The Docker host controls access to those layers.
Review the original
The package list returns the caller's metadata in packages. The administrator can also see a pending review queue. Download the original with administrator-only GET /api/v1/packages/PACKAGE_ID/review, inspect it, and verify the SHA-256 digest. To approve it, post a JSON object with digest (the exact sha256:… value) and tools (the reviewed array of MCP tool definitions, including each name, description and input schema) to /api/v1/packages/PACKAGE_ID/approve. Use the returned package ID verbatim in the instance's profile field; that ID already includes the upload- prefix. Keep source files and archives free of embedded secrets. A trusted host administrator controls the Docker host and storage; private visibility restricts hub API access.
For the bundled Text stats example, the operator can compare the downloaded bytes against the reviewed local source. Replace the package ID below with the one returned at upload. Use the operator's authenticated curl helper.
TOKEN_FILE="$PRIVATE_DIR/admin.token"
PACKAGE_ID='upload-REPLACE_WITH_RETURNED_ID'
REVIEW_DIR=$(mktemp -d)
hub "$HUB_URL/api/v1/packages/$PACKAGE_ID/review" > "$REVIEW_DIR/source.py"
cmp examples/text-stats/server.py "$REVIEW_DIR/source.py"
Continue only after the comparison succeeds and you have inspected the code and schemas. Run the following to construct the approval for those exact bytes. The example reads the Python file as data.
python3 - "$REVIEW_DIR/source.py" > "$REVIEW_DIR/approval.json" <<'PYTHON'
import hashlib
import json
import sys
from pathlib import Path
source = Path(sys.argv[1]).read_bytes()
tools = json.loads(Path("examples/text-stats/tools.json").read_text())
print(json.dumps({"digest": "sha256:" + hashlib.sha256(source).hexdigest(), "tools": tools}))
PYTHON
hub -H 'Content-Type: application/json' --data-binary "@$REVIEW_DIR/approval.json" \
"$HUB_URL/api/v1/packages/$PACKAGE_ID/approve"
The approval response shows approved: true. The package owner can now select the ID as the profile and deploy it. Each worker checks the live tool names and schemas against the approved contract before serving calls.
Reproduce a complete package deployment
After preparing the local pinned worker image and Docker socket, run the upload smoke from the repository root. It creates an isolated temporary installation with two caller identities, exercises Python and OCI uploads, reviews the bytes, calls private and shared instances, and cleans up its test resources.
python3 -B tests/upload_smoke.py --binary bin/daedro-mcp-hub --docker-socket "$DOCKER_SOCKET" --image "$IMAGE_ID"
The operator and local Docker daemon are trusted. Use the deployment and host procedures appropriate to the package's publisher. Security policy · Deploy the approved profile