Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .github/ghcr-verify-context/Dockerfile

This file was deleted.

8 changes: 4 additions & 4 deletions .github/scripts/tools-publish/detect-matrix.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ else
continue
fi
if echo "$changed" | grep -q "^tools/mcp-tools.json$"; then
old_ver=$(git show HEAD~1:tools/mcp-tools.json 2>/dev/null \
| jq -r --arg s "$s" '.tools[] | select(.id | endswith("/" + $s)) | .current // ""' 2>/dev/null || echo "")
new_ver=$(jq -r --arg s "$s" '.tools[] | select(.id | endswith("/" + $s)) | .current' "$REGISTRY")
if [[ -n "$old_ver" && "$old_ver" != "$new_ver" ]]; then
old_blob=$(git show HEAD~1:tools/mcp-tools.json 2>/dev/null \
| jq -c --arg s "$s" '.tools[]? | select(.id | endswith("/" + $s))' 2>/dev/null || echo "")
new_blob=$(jq -c --arg s "$s" '.tools[] | select(.id | endswith("/" + $s))' "$REGISTRY")
if [[ "$old_blob" != "$new_blob" ]]; then
slugs="$slugs $s"
fi
fi
Expand Down
38 changes: 31 additions & 7 deletions .github/scripts/tools-publish/read-tool-manifest.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env bash
# Writes image, version, npm_pkg, npm_ver to GITHUB_OUTPUT for one tool slug.
# Writes image, version, and multiline build_args to GITHUB_OUTPUT for one tool slug.
# Each tool must define either upstream_mcp_npm or upstream_mcp_pypi (not both).
# Usage: TOOL_SLUG=file-manager (env) or first argument.
set -euo pipefail

Expand All @@ -15,11 +16,34 @@ VERSION=$(jq -r --arg s "$SUFFIX" '.tools[] | select(.id | endswith("/" + $s)) |
echo "image=$IMAGE" >> "$GITHUB_OUTPUT"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"

PKG=$(jq -r --arg s "$SUFFIX" '.tools[] | select(.id | endswith("/" + $s)) | .upstream_mcp_npm.package // ""' "$REGISTRY")
NPM_VER=$(jq -r --arg s "$SUFFIX" '.tools[] | select(.id | endswith("/" + $s)) | .upstream_mcp_npm.version // ""' "$REGISTRY")
if [[ -z "$PKG" || -z "$NPM_VER" ]]; then
echo "::error::${REGISTRY}: tool '${SUFFIX}' must define non-empty upstream_mcp_npm.package and upstream_mcp_npm.version" >&2
npm_pkg=$(jq -r --arg s "$SUFFIX" '.tools[] | select(.id | endswith("/" + $s)) | .upstream_mcp_npm.package // ""' "$REGISTRY")
npm_ver=$(jq -r --arg s "$SUFFIX" '.tools[] | select(.id | endswith("/" + $s)) | .upstream_mcp_npm.version // ""' "$REGISTRY")
pypi_pkg=$(jq -r --arg s "$SUFFIX" '.tools[] | select(.id | endswith("/" + $s)) | .upstream_mcp_pypi.package // ""' "$REGISTRY")
pypi_ver=$(jq -r --arg s "$SUFFIX" '.tools[] | select(.id | endswith("/" + $s)) | .upstream_mcp_pypi.version // ""' "$REGISTRY")

has_npm=0
[[ -n "$npm_pkg" && -n "$npm_ver" ]] && has_npm=1
has_pypi=0
[[ -n "$pypi_pkg" && -n "$pypi_ver" ]] && has_pypi=1

if [[ "$has_npm" -eq 1 && "$has_pypi" -eq 1 ]]; then
echo "::error::${REGISTRY}: tool '${SUFFIX}' must not set both upstream_mcp_npm and upstream_mcp_pypi" >&2
exit 1
fi
echo "npm_pkg=$PKG" >> "$GITHUB_OUTPUT"
echo "npm_ver=$NPM_VER" >> "$GITHUB_OUTPUT"
if [[ "$has_npm" -eq 0 && "$has_pypi" -eq 0 ]]; then
echo "::error::${REGISTRY}: tool '${SUFFIX}' must define upstream_mcp_npm or upstream_mcp_pypi" >&2
exit 1
fi

{
echo 'build_args<<BUILD_ARGS_EOF'
if [[ "$has_npm" -eq 1 ]]; then
echo "UPSTREAM_MCP_NPM_PACKAGE=$npm_pkg"
echo "UPSTREAM_MCP_NPM_VERSION=$npm_ver"
fi
if [[ "$has_pypi" -eq 1 ]]; then
echo "UPSTREAM_MCP_PYPI_PACKAGE=$pypi_pkg"
echo "UPSTREAM_MCP_PYPI_VERSION=$pypi_ver"
fi
echo 'BUILD_ARGS_EOF'
} >> "$GITHUB_OUTPUT"
11 changes: 9 additions & 2 deletions .github/scripts/tools-publish/smoke-test-mcp.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
# Pull image by digest and run one MCP initialize JSON-RPC round-trip.
# Env: IMAGE_WITH_DIGEST (e.g. ghcr.io/org/img@sha256:...).
# Env: IMAGE_WITH_DIGEST (e.g. ghcr.io/org/img@sha256:...). Optional TOOL_SLUG for argv quirks.
set -euo pipefail

if [[ -z "${IMAGE_WITH_DIGEST:-}" ]]; then
Expand All @@ -9,8 +9,15 @@ if [[ -z "${IMAGE_WITH_DIGEST:-}" ]]; then
fi

docker pull "$IMAGE_WITH_DIGEST"

# Filesystem MCP expects at least one allowed root on argv; others ignore extra args.
extra=()
if [[ "${TOOL_SLUG:-}" == "file-manager" ]]; then
extra=(/tmp)
fi

RESP=$(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"0.0.1"}}}' \
| timeout 15 docker run --rm -i --network=none "$IMAGE_WITH_DIGEST" /tmp \
| timeout 15 docker run --rm -i --network=none "$IMAGE_WITH_DIGEST" "${extra[@]}" \
| head -1)
echo "$RESP" | jq -e '.result.serverInfo' > /dev/null \
|| { echo "::error::MCP init failed: $RESP"; exit 1; }
67 changes: 0 additions & 67 deletions .github/workflows/ghcr-verify.yml

This file was deleted.

9 changes: 3 additions & 6 deletions .github/workflows/tools-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,7 @@ jobs:
push: true
provenance: false
sbom: false
build-args: |
UPSTREAM_MCP_NPM_PACKAGE=${{ steps.cfg.outputs.npm_pkg }}
UPSTREAM_MCP_NPM_VERSION=${{ steps.cfg.outputs.npm_ver }}
build-args: ${{ steps.cfg.outputs.build_args }}
tags: ${{ steps.cfg.outputs.image }}:${{ steps.cfg.outputs.version }}-ci-arm64-${{ github.run_id }}

- name: Build and push (linux/amd64)
Expand All @@ -95,9 +93,7 @@ jobs:
push: true
provenance: false
sbom: false
build-args: |
UPSTREAM_MCP_NPM_PACKAGE=${{ steps.cfg.outputs.npm_pkg }}
UPSTREAM_MCP_NPM_VERSION=${{ steps.cfg.outputs.npm_ver }}
build-args: ${{ steps.cfg.outputs.build_args }}
tags: ${{ steps.cfg.outputs.image }}:${{ steps.cfg.outputs.version }}-ci-amd64-${{ github.run_id }}

- name: Merge multi-arch manifest
Expand All @@ -117,6 +113,7 @@ jobs:
- name: Smoke test (MCP init handshake)
env:
IMAGE_WITH_DIGEST: ${{ steps.cfg.outputs.image }}@${{ steps.merge.outputs.digest }}
TOOL_SLUG: ${{ matrix.slug }}
run: bash .github/scripts/tools-publish/smoke-test-mcp.sh

- name: Summary
Expand Down
13 changes: 6 additions & 7 deletions doc/tool-engine/manual-publish.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,20 @@ After a successful push, get the digest:
podman image inspect "${IMAGE}:${VERSION}" --format '{{index .RepoDigests 0}}'
```

Update the `sha256:…` value in the matching `versions[]` entry in **`tools/mcp-tools.json`**. The app fetches this file from GitHub at runtime; the embedded `src-tauri/src/modules/tool_engine/tools.json` is the offline fallback.
Update the `sha256:…` value in the matching `versions[]` entry in **`tools/mcp-tools.json`**. The app fetches this file from GitHub at runtime and embeds the same file at compile time as the offline fallback.

---

## Updating upstream npm versions
## Updating upstream npm and PyPI versions

Run the update script (like `npm update` for tool images):
Run the update script (like `npm update` / PyPI bump for tool images):

```bash
./tools/update-upstream.sh # check all tools
./tools/update-upstream.sh file-manager # check one tool
```

This checks the npm registry for newer versions, bumps `mcp-tools.json`, and prints a summary. Commit, push, and CI builds only the affected tools.
`./tools/update-upstream.sh` checks the **npm** registry for tools that declare `upstream_mcp_npm` and the **PyPI** registry for tools that declare `upstream_mcp_pypi`, bumps `mcp-tools.json` when a newer version exists, and prints a summary. Commit, push, and CI builds only the affected tools. In PR descriptions, note that the script may have changed either npm or PyPI pins (or both) depending on the tool.

---

Expand Down Expand Up @@ -132,8 +132,7 @@ CI passes these as `docker build` args so you bump the npm version in the regist

## Files

- **`tools/mcp-tools.json`** — tool registry (all tools, versions, digests, npm). CI and the app read this.
- **`tools/mcp-tools.json`** — single-source tool registry (all tools, versions, digests, upstream). CI, the app at runtime, and the embedded offline fallback (`include_str!`) all read this file.
- **`tools/<slug>/Dockerfile`** — image build context.
- **`tools/update-upstream.sh`** — bump upstream npm versions (like `npm update`).
- **`src-tauri/src/modules/tool_engine/tools.json`** — embedded catalog (offline fallback). Update after publish.
- **`tools/update-upstream.sh`** — bump upstream **npm** and **PyPI** package versions (registry checks for each tool’s ecosystem).
- **`.github/workflows/tools-publish.yml`** — CI workflow.
1 change: 1 addition & 0 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ socket2 = "0.5"
fastrand = "2"
tauri-plugin-dialog = "2"

[dev-dependencies]
tempfile = "3"

Loading