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
64 changes: 63 additions & 1 deletion .github/workflows/release-mcp-registry.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,21 @@ jobs:

echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"

- name: Check the server name is consistent across packages
- name: Check the server metadata is consistent
shell: bash
run: |
server_name="$(jq -r '.name' server.json)"
echo "Server name: ${server_name}"

remote_url="https://api.smbcloud.xyz/v1/mcp"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning — The workflow now requires the server.json to include the Streamable HTTP remote URL; ensure this does not break existing release processes if server.json is not updated accordingly.

Comment thread
setoelkahfi marked this conversation as resolved.
if ! jq -e --arg url "${remote_url}" \
'any(.remotes[]?; .type == "streamable-http" and .url == $url)' \
server.json >/dev/null; then
Comment thread
coderabbitai[bot] marked this conversation as resolved.
echo "server.json is missing the Streamable HTTP remote ${remote_url}." >&2
exit 1
fi
echo "MCP_REMOTE_URL=${remote_url}" >> "$GITHUB_ENV"

# npm proves ownership through `mcpName` in the published package.json,
# which is generated by this script at release time.
grep -q "mcpName: \"${server_name}\"" npm/scripts/render-main-package.cjs
Expand All @@ -47,6 +56,59 @@ jobs:
xcrs_server_name="$(jq -r '.name' server-xcrs.json)"
grep -q "mcp-name: ${xcrs_server_name}" crates/xcrs/README.md

- name: Verify the hosted MCP endpoint
shell: bash
run: |
remote_url="${MCP_REMOTE_URL}"
response_headers="$(mktemp)"
response_body="$(mktemp)"
trap 'rm -f "${response_headers}" "${response_body}"' EXIT

request_body='{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smbcloud-registry-release-check","version":"1"}}}'
if ! http_status="$(curl --http1.1 --silent --show-error \
--connect-timeout 10 \
--max-time 20 \
--retry 2 \
--retry-all-errors \
--retry-delay 2 \
--dump-header "${response_headers}" \
--output "${response_body}" \
--write-out '%{http_code}' \
--header 'Accept: application/json, text/event-stream' \
--header 'Content-Type: application/json' \
--data "${request_body}" \
"${remote_url}")"; then
echo "Failed to reach the hosted MCP endpoint ${remote_url}." >&2
exit 1
fi

if [ "${http_status}" = "401" ]; then
if ! grep -Eiq '^www-authenticate:[[:space:]]*Bearer([[:space:]]|$)' "${response_headers}"; then
echo "The hosted MCP endpoint returned 401 without a Bearer challenge." >&2
cat "${response_headers}" >&2
exit 1
fi
echo "The hosted MCP endpoint returned the expected authentication challenge."
elif [ "${http_status}" = "200" ]; then
if jq -e \
'.jsonrpc == "2.0" and .id == 1 and (has("result") or has("error"))' \
"${response_body}" >/dev/null 2>&1 || \
sed -n 's/^data:[[:space:]]*//p' "${response_body}" | \
jq -se 'any(.[]; .jsonrpc == "2.0" and .id == 1 and (has("result") or has("error")))' \
>/dev/null; then
echo "The hosted MCP endpoint returned a valid initialize response."
else
echo "The hosted MCP endpoint returned HTTP 200 without a valid MCP response." >&2
cat "${response_body}" >&2
exit 1
fi
else
echo "The hosted MCP endpoint returned unexpected HTTP status ${http_status}." >&2
cat "${response_headers}" >&2
cat "${response_body}" >&2
exit 1
fi

- name: Set release versions in server metadata
shell: bash
run: |
Expand Down
9 changes: 6 additions & 3 deletions docs/mcp-registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ The repository publishes two MCP servers to the [official MCP Registry](https://
- **`io.github.smbcloudXYZ/xcrs`** — **XCRS Mobile & TV Automation**, available through `xcrs --mcp` or `smb --mcp --scope automation` for Xcode, ControlKit, CoreDevice, and adb workflows.

The registry is a metadata index — it doesn't host binaries. The smbCloud
listing points at packages published to npm and NuGet, while the standalone
XCRS listing points at the `xcrs` crate on crates.io.
listing offers the hosted Streamable HTTP server as well as packages published
to npm and NuGet, while the standalone XCRS listing points at the `xcrs` crate
on crates.io.

For running and configuring the server itself, see [MCP Server](./mcp.md).

Expand Down Expand Up @@ -48,7 +49,9 @@ Publishing under
`smbcloud.xyz` plus an Ed25519 private key stored as a repo secret. OIDC needs
no secret at all, so that's what we use.

### Which packages are listed
### Available connections

- **Hosted** — Streamable HTTP at `https://api.smbcloud.xyz/v1/mcp`.

- **npm** — `@smbcloud/cli`, launched as `npx @smbcloud/cli --mcp`. The package
declares a single binary (`smb`), so `npx` resolves it despite the name
Expand Down
6 changes: 6 additions & 0 deletions server.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
"source": "github",
"id": "597171611"
},
"remotes": [
Comment thread
setoelkahfi marked this conversation as resolved.
Comment thread
setoelkahfi marked this conversation as resolved.
{
"type": "streamable-http",
"url": "https://api.smbcloud.xyz/v1/mcp"
}
],
"packages": [
{
"registryType": "npm",
Expand Down
Loading