diff --git a/docs/toolhive/guides-cli/advanced-cicd.mdx b/docs/toolhive/guides-cli/advanced-cicd.mdx new file mode 100644 index 0000000..877d5f1 --- /dev/null +++ b/docs/toolhive/guides-cli/advanced-cicd.mdx @@ -0,0 +1,327 @@ +--- +title: Advanced CI/CD with ToolHive +description: + Advanced CI/CD patterns for building and deploying MCP server containers with + ToolHive. +--- + +This guide covers advanced CI/CD patterns for production environments using +ToolHive's [`thv build`](../reference/cli/thv_build.md) command. These patterns +include multi-architecture builds, supply chain security, and efficient change +detection. + +## Prerequisites + +Before implementing these advanced patterns, ensure you have: + +- Basic understanding of [`thv build`](./build-containers.mdx) command +- Experience with CI/CD pipelines (GitHub Actions, GitLab CI, etc.) +- Container registry access for pushing images +- Understanding of Docker Buildx for multi-architecture builds + +## Multi-architecture builds + +Build containers for multiple architectures (amd64, arm64) using Docker Buildx: + +```yaml +name: Multi-arch Build +on: + push: + tags: ['v*'] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Install ToolHive + run: | + # Install ToolHive CLI (replace with your preferred installation method) + # See: https://github.com/stacklok/toolhive/releases + wget https://github.com/stacklok/toolhive/releases/latest/download/toolhive_linux_amd64.tar.gz + tar -xzf toolhive_linux_amd64.tar.gz + sudo install -m 0755 thv /usr/local/bin/ + + - name: Generate Dockerfile + run: | + thv build --dry-run --output Dockerfile uvx://mcp-server-git + + - name: Build multi-arch container + run: | + docker buildx build \ + --platform linux/amd64,linux/arm64 \ + --tag ghcr.io/myorg/mcp-server:${{ github.ref_name }} \ + --push \ + . +``` + +## Supply chain security + +Enhance security with SBOM generation, provenance attestation, and image +signing: + +```yaml +name: Secure Build +on: + push: + tags: ['v*'] + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + id-token: write + steps: + - uses: actions/checkout@v4 + + - name: Install Cosign + uses: sigstore/cosign-installer@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Install ToolHive + run: | + # Install ToolHive CLI (replace with your preferred installation method) + # See: https://github.com/stacklok/toolhive/releases + wget https://github.com/stacklok/toolhive/releases/latest/download/toolhive_linux_amd64.tar.gz + tar -xzf toolhive_linux_amd64.tar.gz + sudo install -m 0755 thv /usr/local/bin/ + + - name: Generate Dockerfile + run: | + thv build --dry-run --output Dockerfile uvx://mcp-server-git + + - name: Build with security features + uses: docker/build-push-action@v6 + id: build + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + tags: ghcr.io/myorg/mcp-server:${{ github.ref_name }} + sbom: true # Generate Software Bill of Materials + provenance: true # Generate build provenance + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Sign container image + env: + DIGEST: ${{ steps.build.outputs.digest }} + run: | + cosign sign --yes ghcr.io/myorg/mcp-server@${DIGEST} +``` + +## Efficient change detection + +Build only when relevant files change to optimize CI/CD performance: + +```yaml +name: Conditional Build +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + detect-changes: + runs-on: ubuntu-latest + outputs: + build_needed: ${{ steps.changes.outputs.build_needed }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 2 + + - name: Detect changes + id: changes + run: | + # Check if MCP server configs or Dockerfiles changed + if git diff --name-only HEAD~1..HEAD | grep -E "(mcp-configs/|Dockerfile|\.thv)"; then + echo "build_needed=true" >> $GITHUB_OUTPUT + else + echo "build_needed=false" >> $GITHUB_OUTPUT + fi + + build: + needs: detect-changes + if: needs.detect-changes.outputs.build_needed == 'true' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install ToolHive + run: | + # Install ToolHive CLI (replace with your preferred installation method) + # See: https://github.com/stacklok/toolhive/releases + wget https://github.com/stacklok/toolhive/releases/latest/download/toolhive_linux_amd64.tar.gz + tar -xzf toolhive_linux_amd64.tar.gz + sudo install -m 0755 thv /usr/local/bin/ + + - name: Build containers + run: | + thv build --tag ghcr.io/myorg/mcp-server:latest uvx://mcp-server-git +``` + +## Matrix builds for multiple servers + +Build multiple MCP servers in parallel using matrix strategies: + +```yaml +name: Matrix Build +on: + push: + tags: ['v*'] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + server: + - name: git-server + scheme: uvx://mcp-server-git + - name: filesystem-server + scheme: npx://@modelcontextprotocol/server-filesystem + - name: custom-server + scheme: go://github.com/myorg/custom-mcp-server@latest + steps: + - uses: actions/checkout@v4 + + - name: Install ToolHive + run: | + # Install ToolHive CLI (replace with your preferred installation method) + # See: https://github.com/stacklok/toolhive/releases + wget https://github.com/stacklok/toolhive/releases/latest/download/toolhive_linux_amd64.tar.gz + tar -xzf toolhive_linux_amd64.tar.gz + sudo install -m 0755 thv /usr/local/bin/ + + - name: Build ${{ matrix.server.name }} + run: | + thv build --tag ghcr.io/myorg/${{ matrix.server.name }}:${{ github.ref_name }} \ + ${{ matrix.server.scheme }} + + - name: Push ${{ matrix.server.name }} + run: | + docker push ghcr.io/myorg/${{ matrix.server.name }}:${{ github.ref_name }} +``` + +## Vulnerability scanning + +Integrate security scanning into your build pipeline: + +```yaml +name: Secure Build with Scanning +on: + push: + tags: ['v*'] + +jobs: + build-and-scan: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install ToolHive + run: | + # Install ToolHive CLI (replace with your preferred installation method) + # See: https://github.com/stacklok/toolhive/releases + wget https://github.com/stacklok/toolhive/releases/latest/download/toolhive_linux_amd64.tar.gz + tar -xzf toolhive_linux_amd64.tar.gz + sudo install -m 0755 thv /usr/local/bin/ + + - name: Build container + run: | + thv build --tag mcp-server:scan uvx://mcp-server-git + + - name: Run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: 'mcp-server:scan' + format: 'sarif' + output: 'trivy-results.sarif' + + - name: Upload Trivy scan results + uses: github/codeql-action/upload-sarif@v3 + if: always() + with: + sarif_file: 'trivy-results.sarif' + + - name: Tag and push if scan passes + run: | + docker tag mcp-server:scan ghcr.io/myorg/mcp-server:${{ github.ref_name }} + docker push ghcr.io/myorg/mcp-server:${{ github.ref_name }} +``` + +## GitLab CI example + +For GitLab CI users, here's an equivalent pipeline: + +```yaml +# .gitlab-ci.yml +stages: + - build + - security + - deploy + +variables: + DOCKER_DRIVER: overlay2 + DOCKER_TLS_CERTDIR: '/certs' + +build: + stage: build + image: docker:latest + services: + - docker:dind + before_script: + - | + # Install ToolHive CLI + wget https://github.com/stacklok/toolhive/releases/latest/download/toolhive_linux_amd64.tar.gz + tar -xzf toolhive_linux_amd64.tar.gz + install -m 0755 thv /usr/local/bin/ + - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY + script: + - thv build --tag $CI_REGISTRY_IMAGE/mcp-server:$CI_COMMIT_TAG + uvx://mcp-server-git + - docker push $CI_REGISTRY_IMAGE/mcp-server:$CI_COMMIT_TAG + only: + - tags + +security_scan: + stage: security + image: aquasec/trivy:latest + script: + - trivy image --exit-code 1 --severity HIGH,CRITICAL + $CI_REGISTRY_IMAGE/mcp-server:$CI_COMMIT_TAG + only: + - tags +``` + +## Best practices + +When implementing advanced CI/CD patterns: + +1. **Use specific tags** instead of `latest` for production deployments +2. **Implement proper caching** to speed up builds +3. **Scan for vulnerabilities** before pushing to production registries +4. **Sign images** for supply chain security +5. **Use matrix builds** for multiple MCP servers +6. **Implement change detection** to avoid unnecessary builds +7. **Store sensitive data** in CI/CD secrets, not in code + +## Related information + +- [Build MCP server containers](./build-containers.mdx) +- [Run MCP servers in Kubernetes](../guides-k8s/run-mcp-k8s.md) +- [`thv build` command reference](../reference/cli/thv_build.md) +- [Secrets management](./secrets-management.mdx) diff --git a/docs/toolhive/guides-cli/build-containers.mdx b/docs/toolhive/guides-cli/build-containers.mdx new file mode 100644 index 0000000..408b527 --- /dev/null +++ b/docs/toolhive/guides-cli/build-containers.mdx @@ -0,0 +1,393 @@ +--- +title: Build MCP server containers +description: + How to build MCP server containers without running them using the ToolHive + CLI. +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +This guide explains how to use the [`thv build`](../reference/cli/thv_build.md) +command to build MCP server containers from protocol schemes without running +them. This is useful for pre-building containers for Kubernetes deployments, +CI/CD pipelines, and container registry workflows. + +## Overview + +The `thv build` command allows you to build containers from protocol schemes +(`uvx://`, `npx://`, `go://`) without immediately running them. This provides +several benefits: + +- **Pre-build containers** for faster deployment in Kubernetes environments +- **Separate build and run phases** in CI/CD pipelines +- **Custom image tagging** for container registry workflows +- **Dockerfile generation** for inspection and customization +- **Build validation** before deployment + +## Basic usage + +To build a container from a protocol scheme: + +```bash +thv build +``` + +For example: + +```bash +# Build a Python MCP server using uvx +thv build uvx://mcp-server-git + +# Build a Node.js MCP server using npx +thv build npx://@modelcontextprotocol/server-filesystem + +# Build a Go MCP server +thv build go://github.com/example/my-mcp-server@latest +``` + +:::info What's happening? + +When you run `thv build`, ToolHive: + +1. Detects the protocol scheme and extracts the package reference +2. Generates a Dockerfile based on the appropriate template +3. Builds a Docker image with the package installed +4. Tags the image with an auto-generated name or your custom tag +5. Displays the built image name for use with other tools + +::: + +## Custom image tagging + +Use the `--tag` (or `-t`) flag to specify a custom name and tag for the built +image: + +```bash +thv build --tag my-custom-name:latest npx://@modelcontextprotocol/server-filesystem +``` + +This is particularly useful for: + +- **Container registries**: Tag images for pushing to registries +- **Kubernetes deployments**: Use predictable image names in manifests +- **Version management**: Tag images with specific versions + +### Tagging examples + + + + +Build and tag for pushing to a container registry: + +```bash +# Build and tag for Docker Hub +thv build --tag myusername/mcp-git-server:v1.0.0 uvx://mcp-server-git + +# Build and tag for GitHub Container Registry +thv build --tag ghcr.io/myorg/mcp-filesystem:latest npx://@modelcontextprotocol/server-filesystem + +# Push to registry +docker push ghcr.io/myorg/mcp-filesystem:latest +``` + + + + +Build images with predictable names for Kubernetes manifests: + +```bash +# Build with a consistent tag +thv build --tag mcp-servers/git-server:stable uvx://mcp-server-git + +# Use in Kubernetes manifest +# spec: +# image: mcp-servers/git-server:stable +``` + + + + +Build multiple versions of the same server: + +```bash +# Build different versions +thv build --tag mcp-git:v1.0.0 uvx://mcp-server-git@1.0.0 +thv build --tag mcp-git:v1.1.0 uvx://mcp-server-git@1.1.0 +thv build --tag mcp-git:latest uvx://mcp-server-git@latest +``` + + + + +## Protocol schemes + +The `thv build` command supports the same protocol schemes as +[`thv run`](./run-mcp-servers.mdx): + +### Python (uvx) + +Build Python-based MCP servers using the uv package manager: + +```bash +# Build with auto-generated name +thv build uvx://mcp-server-git + +# Build with custom tag +thv build --tag my-git-server:latest uvx://mcp-server-git@1.2.0 +``` + +### Node.js (npx) + +Build Node.js-based MCP servers using npm: + +```bash +# Build with auto-generated name +thv build npx://@modelcontextprotocol/server-filesystem + +# Build with custom tag +thv build --tag filesystem-server:v2.0 npx://@modelcontextprotocol/server-filesystem@2.0.0 +``` + +### Go + +Build Go-based MCP servers: + +```bash +# Build from remote Go module +thv build --tag grafana-mcp:latest go://github.com/grafana/mcp-grafana/cmd/mcp-grafana@latest + +# Build from local Go project +thv build --tag my-local-server:dev go://./cmd/my-mcp-server +``` + +## Dockerfile generation + +Use the `--dry-run` flag to generate the Dockerfile without building the image: + +```bash +# Output Dockerfile to stdout +thv build --dry-run uvx://mcp-server-git + +# Save Dockerfile to a file +thv build --dry-run --output Dockerfile.mcp-git uvx://mcp-server-git +``` + +This is useful for: + +- **Inspecting the build process** before building +- **Customizing Dockerfiles** for specific requirements +- **Understanding dependencies** and build steps +- **Debugging build issues** + +### Example Dockerfile output + +```dockerfile +# Generated by: thv build --dry-run uvx://mcp-server-git +FROM python:3.12-slim + +# Install uv +RUN pip install uv + +# Install the package +RUN uv tool install mcp-server-git + +# Set the entrypoint +ENTRYPOINT ["uv", "tool", "run", "mcp-server-git"] +``` + +## Kubernetes workflows + +The `thv build` command is especially useful for Kubernetes deployments where +you want to pre-build containers before deploying them. + +### Pre-build workflow + +1. **Build the container** with a specific tag: + + ```bash + thv build --tag ghcr.io/myorg/mcp-git:v1.0.0 uvx://mcp-server-git@1.0.0 + ``` + +2. **Push to container registry**: + + ```bash + docker push ghcr.io/myorg/mcp-git:v1.0.0 + ``` + +3. **Deploy to Kubernetes** using the pre-built image: + ```yaml + apiVersion: toolhive.stacklok.dev/v1alpha1 + kind: MCPServer + metadata: + name: git-server + namespace: production + spec: + image: ghcr.io/myorg/mcp-git:v1.0.0 + transport: stdio + permissionProfile: + type: builtin + name: network + ``` + +### CI/CD integration + +Integrate `thv build` into your CI/CD pipeline for automated container building: + +```yaml +# Example GitHub Actions workflow +name: Build and Deploy MCP Server +on: + push: + tags: ['v*'] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install ToolHive + run: | + # Install ToolHive CLI (replace with your preferred installation method) + # See: https://github.com/stacklok/toolhive/releases + wget https://github.com/stacklok/toolhive/releases/latest/download/toolhive_linux_amd64.tar.gz + tar -xzf toolhive_linux_amd64.tar.gz + sudo install -m 0755 thv /usr/local/bin/ + + - name: Log in to Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build MCP server + run: | + thv build --tag ghcr.io/${{ github.repository }}/mcp-server:${{ github.ref_name }} \ + uvx://mcp-server-git@${{ github.ref_name }} + + - name: Push to registry + run: | + docker push ghcr.io/${{ github.repository }}/mcp-server:${{ github.ref_name }} +``` + +For more advanced CI/CD patterns including multi-architecture builds, supply +chain security, and change detection, see the +[Advanced CI/CD with ToolHive](./advanced-cicd.mdx) guide. + +## Advanced usage + +### Build with custom CA certificates + +For corporate environments with custom certificate authorities: + +```bash +# Use global CA certificate configuration +thv config set-ca-cert /path/to/corporate-ca.crt +thv build uvx://internal-mcp-server + +# Override CA certificate for specific build +thv build --ca-cert /path/to/special-ca.crt uvx://special-server +``` + +### Build local Go projects + +Build MCP servers from local Go projects: + +```bash +# Build from current directory +cd my-go-mcp-project +thv build --tag my-server:dev go://. + +# Build from relative path +thv build --tag my-server:dev go://./cmd/server + +# Build from absolute path +thv build --tag my-server:dev go:///path/to/my-project +``` + +## Comparison with thv run + +| Feature | `thv build` | `thv run` | +| ------------------------- | ------------------------ | ------------------------ | +| **Purpose** | Build containers only | Build and run containers | +| **Output** | Container image | Running MCP server | +| **Use case** | Pre-building, CI/CD | Development, testing | +| **Kubernetes** | Pre-build for deployment | Direct development | +| **Custom tagging** | ✅ `--tag` flag | ❌ Auto-generated names | +| **Dockerfile generation** | ✅ `--dry-run` flag | ❌ Not available | + +## Next steps + +- Use built containers with [`thv run`](./run-mcp-servers.mdx) for local + development +- Deploy pre-built containers to [Kubernetes](../guides-k8s/run-mcp-k8s.md) +- Set up [CI/CD pipelines](#cicd-integration) for automated building +- Learn about [container registry workflows](#custom-image-tagging) + +## Related information + +- [`thv build` command reference](../reference/cli/thv_build.md) +- [Run MCP servers](./run-mcp-servers.mdx) +- [Run MCP servers in Kubernetes](../guides-k8s/run-mcp-k8s.md) +- [Custom permissions](./custom-permissions.mdx) + +## Troubleshooting + +
+Build fails with network errors + +If builds fail with network connectivity issues: + +1. **Check internet connectivity** for downloading packages +2. **Configure CA certificates** for corporate environments: + ```bash + thv config set-ca-cert /path/to/corporate-ca.crt + ``` +3. **Use proxy settings** if required by your network +4. **Verify package names** and versions exist in the respective registries + +
+ +
+Invalid image tag format + +If you get image tag validation errors: + +1. **Use valid Docker image tag format**: `name:tag` or `registry/name:tag` +2. **Avoid special characters** except hyphens, underscores, and dots +3. **Use lowercase names** for compatibility +4. **Check tag length limits** (typically 128 characters) + +Example valid tags: + +```bash +thv build --tag my-server:latest uvx://package +thv build --tag ghcr.io/org/server:v1.0.0 npx://package +``` + +
+ +
+Package not found errors + +If the build fails because a package cannot be found: + +1. **Verify package exists** in the respective registry: + - Python: Check [PyPI](https://pypi.org/) + - Node.js: Check [npm](https://www.npmjs.com/) + - Go: Verify the module path and version + +2. **Check version specifiers**: + + ```bash + # Correct version formats + thv build uvx://package@1.0.0 + thv build npx://package@latest + thv build go://github.com/user/repo@v1.0.0 + ``` + +3. **For Go modules**, ensure the path includes the correct import path + +
diff --git a/sidebars.ts b/sidebars.ts index 6d0bb4a..7d71db0 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -66,6 +66,8 @@ const sidebars: SidebarsConfig = { 'toolhive/guides-cli/install', 'toolhive/guides-cli/registry', 'toolhive/guides-cli/run-mcp-servers', + 'toolhive/guides-cli/build-containers', + 'toolhive/guides-cli/advanced-cicd', 'toolhive/guides-cli/manage-mcp-servers', 'toolhive/guides-cli/secrets-management', 'toolhive/guides-cli/client-configuration',