mirror of
https://github.com/anthropics/claude-plugins-official.git
synced 2026-05-18 20:22:40 +00:00
Compare commits
4 Commits
tobin/chec
...
tobin/fix-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f2f08f955 | ||
|
|
791f2de6ce | ||
|
|
e98784f00e | ||
|
|
237a6b9707 |
@@ -18,7 +18,7 @@
|
||||
"source": "git-subdir",
|
||||
"url": "https://github.com/42Crunch-AI/claude-plugins.git",
|
||||
"path": "plugins/api-security-testing",
|
||||
"ref": "v1.0.1",
|
||||
"ref": "v1.5.5",
|
||||
"sha": "faf5305385de8afed9468904e8639be737aff39e"
|
||||
},
|
||||
"homepage": "https://42crunch.com"
|
||||
@@ -1049,8 +1049,8 @@
|
||||
"source": {
|
||||
"source": "github",
|
||||
"repo": "jfrog/claude-plugin",
|
||||
"commit": "761921eaa12b845beba1688d699a2d45091dfe83",
|
||||
"sha": "d80db066e219aab8190f3dc4a463b71a3a180250"
|
||||
"commit": "259c8e718266c16e99b4f30ae9b1ed0f9f00d98d",
|
||||
"sha": "259c8e718266c16e99b4f30ae9b1ed0f9f00d98d"
|
||||
},
|
||||
"homepage": "https://jfrog.com"
|
||||
},
|
||||
@@ -1654,7 +1654,8 @@
|
||||
"source": {
|
||||
"source": "url",
|
||||
"url": "https://github.com/RevenueCat/rc-claude-code-plugin.git",
|
||||
"sha": "af7cb77996aee4e7e3c109c5afec81f716139032"
|
||||
"path": "revenuecat",
|
||||
"sha": "407e4651ff74dbaf47c457948ab540e620403c2a"
|
||||
},
|
||||
"homepage": "https://www.revenuecat.com"
|
||||
},
|
||||
@@ -1675,7 +1676,8 @@
|
||||
"source": {
|
||||
"source": "url",
|
||||
"url": "https://github.com/RevenueCat/rc-claude-code-plugin.git",
|
||||
"sha": "af7cb77996aee4e7e3c109c5afec81f716139032"
|
||||
"path": "revenuecat",
|
||||
"sha": "407e4651ff74dbaf47c457948ab540e620403c2a"
|
||||
},
|
||||
"homepage": "https://www.revenuecat.com"
|
||||
},
|
||||
@@ -2007,7 +2009,8 @@
|
||||
"source": {
|
||||
"source": "url",
|
||||
"url": "https://github.com/sumup/sumup-skills.git",
|
||||
"sha": "0fd0a911ecaffd7187fe35e914d8ead6de584ffd"
|
||||
"path": "providers/claude/plugin",
|
||||
"sha": "a4b5a9789e10e27fb375b68279bb0916074b8dd4"
|
||||
},
|
||||
"homepage": "https://www.sumup.com/"
|
||||
},
|
||||
@@ -2247,7 +2250,8 @@
|
||||
"source": {
|
||||
"source": "url",
|
||||
"url": "https://github.com/zilliztech/zilliz-plugin.git",
|
||||
"sha": "17cf04e6a3c272320b707d429484e4c00b3bec0b"
|
||||
"path": "plugins/zilliz",
|
||||
"sha": "e960396da0bd0b1cb219fa97e3bcbb425ee1abbd"
|
||||
},
|
||||
"homepage": "https://docs.zilliz.com"
|
||||
},
|
||||
|
||||
8
.github/workflows/bump-plugin-shas.yml
vendored
8
.github/workflows/bump-plugin-shas.yml
vendored
@@ -1,8 +1,10 @@
|
||||
name: Bump Plugin SHAs
|
||||
|
||||
# Weekly sweep: for each external entry whose upstream HEAD has moved past
|
||||
# Nightly sweep: for each external entry whose upstream HEAD has moved past
|
||||
# its pinned SHA, validate at the new SHA with `claude plugin validate`
|
||||
# inline, then open one PR with all passing bumps.
|
||||
# inline, then open one PR with all passing bumps. Each run force-resets the
|
||||
# bump/plugin-shas branch, so a previous night's unmerged PR is replaced (and
|
||||
# its review state discarded) — review and merge same-day to avoid churn.
|
||||
#
|
||||
# Bot-free — uses the default GITHUB_TOKEN. PRs opened with GITHUB_TOKEN don't
|
||||
# trigger on:pull_request workflows, so the policy scan (`Scan Plugins`, a
|
||||
@@ -14,7 +16,7 @@ name: Bump Plugin SHAs
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '23 7 * * 1' # Monday 07:23 UTC
|
||||
- cron: '23 7 * * *' # Daily 07:23 UTC
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
max_bumps:
|
||||
|
||||
129
.github/workflows/check-mcp-urls.yml
vendored
Normal file
129
.github/workflows/check-mcp-urls.yml
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
name: Check MCP URLs
|
||||
|
||||
# Liveness check for http/sse MCP server URLs declared by plugins vendored
|
||||
# in this repo. Catches typos in new submissions and upstream endpoints that
|
||||
# disappear after merge.
|
||||
#
|
||||
# Scope: only plugins whose files live in this working tree (marketplace
|
||||
# entries with a string `source`, e.g. "./plugins/foo"). External entries
|
||||
# are pinned to an upstream repo at a SHA — reading their .mcp.json would
|
||||
# mean cloning every upstream on each run, which is slow and flaky. Those
|
||||
# are out of scope for now.
|
||||
#
|
||||
# What counts as "alive": anything that proves the hostname/path resolves to
|
||||
# a server. 401/403/405/5xx all pass — auth and method errors are expected
|
||||
# without credentials. Only 404/410 and connection/DNS/TLS failures fail.
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- '.claude-plugin/marketplace.json'
|
||||
- 'plugins/**'
|
||||
- 'external_plugins/**'
|
||||
- '.github/workflows/check-mcp-urls.yml'
|
||||
schedule:
|
||||
- cron: '0 6 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Discover and probe MCP server URLs
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
MARKETPLACE=".claude-plugin/marketplace.json"
|
||||
|
||||
# Each line: "<plugin>\t<server>\t<url>". Marketplace entries with a
|
||||
# string `source` are local paths; objects describe an external repo
|
||||
# pinned at a SHA, which we don't have checked out — skip those.
|
||||
discover() {
|
||||
jq -r '.plugins[] | select(.source | type == "string") | "\(.name)\t\(.source)"' "$MARKETPLACE" |
|
||||
while IFS=$'\t' read -r plugin src; do
|
||||
dir="${src#./}"
|
||||
[[ -d "$dir" ]] || continue
|
||||
for cfg in "$dir/.mcp.json" "$dir/mcp.json" "$dir/.claude-plugin/plugin.json"; do
|
||||
[[ -f "$cfg" ]] || continue
|
||||
# MCP config comes in two shapes: a bare map of server name ->
|
||||
# config, or wrapped under a top-level "mcpServers" key (also
|
||||
# the shape inside plugin.json). Normalize, then keep entries
|
||||
# with an http/sse type and a string url.
|
||||
jq -r --arg plugin "$plugin" '
|
||||
(if (type == "object" and has("mcpServers")) then .mcpServers else . end)
|
||||
| to_entries[]
|
||||
| select((.value | type) == "object")
|
||||
| select(.value.type == "http" or .value.type == "sse")
|
||||
| select(.value.url | type == "string")
|
||||
| "\($plugin)\t\(.key)\t\(.value.url)"
|
||||
' "$cfg" 2>/dev/null || true
|
||||
done
|
||||
done | sort -u
|
||||
}
|
||||
|
||||
# Returns 0 on pass, 1 on fail; prints "PASS|FAIL <code> <note>".
|
||||
probe() {
|
||||
local url="$1"
|
||||
local code
|
||||
# HEAD first — cheap and covers plain web endpoints. -L follows
|
||||
# redirects so a permanent redirect to a live page still passes.
|
||||
code="$(curl -sS -o /dev/null -w '%{http_code}' \
|
||||
--connect-timeout 10 --max-time 10 \
|
||||
--retry 2 --retry-delay 2 \
|
||||
-L -I "$url" 2>/dev/null || echo "000")"
|
||||
|
||||
# MCP endpoints typically reject HEAD (404/405) but answer POST
|
||||
# with a JSON-RPC body. Retry as a real MCP client would.
|
||||
if [[ "$code" == "000" || "$code" == "404" || "$code" == "405" ]]; then
|
||||
code="$(curl -sS -o /dev/null -w '%{http_code}' \
|
||||
--connect-timeout 10 --max-time 10 \
|
||||
--retry 2 --retry-delay 2 \
|
||||
-L -X POST \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'Accept: application/json, text/event-stream' \
|
||||
--data '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"ci","version":"0"}}}' \
|
||||
"$url" 2>/dev/null || echo "000")"
|
||||
fi
|
||||
|
||||
case "$code" in
|
||||
000) echo "FAIL $code unreachable"; return 1 ;;
|
||||
404|410) echo "FAIL $code gone"; return 1 ;;
|
||||
*) echo "PASS $code"; return 0 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
entries="$(discover)"
|
||||
if [[ -z "$entries" ]]; then
|
||||
echo "::notice::No http/sse MCP server URLs found in vendored plugins."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
failures=0
|
||||
printf '%-24s %-18s %-52s %s\n' "PLUGIN" "SERVER" "URL" "RESULT"
|
||||
while IFS=$'\t' read -r plugin server url; do
|
||||
# Skip URLs with template placeholders — they need user config
|
||||
# and can't be probed as-is.
|
||||
if [[ "$url" == *'${'* || "$url" == *'{{'* ]]; then
|
||||
printf '%-24s %-18s %-52s %s\n' "$plugin" "$server" "$url" "SKIP templated"
|
||||
continue
|
||||
fi
|
||||
result="$(probe "$url")" || true
|
||||
printf '%-24s %-18s %-52s %s\n' "$plugin" "$server" "$url" "$result"
|
||||
if [[ "$result" == FAIL* ]]; then
|
||||
failures=$((failures + 1))
|
||||
echo "::error::MCP server URL for plugin '$plugin' (server '$server') is unreachable: $url ($result)"
|
||||
fi
|
||||
done <<< "$entries"
|
||||
|
||||
echo
|
||||
if (( failures > 0 )); then
|
||||
echo "::error::$failures MCP server URL(s) failed liveness check."
|
||||
exit 1
|
||||
fi
|
||||
echo "All MCP server URLs reachable."
|
||||
Reference in New Issue
Block a user