main
claude/smbcloud-github-app-k9641p
development
feature/apps
feature/build-release
feature/ci-docs
feature/ci-ruby-gems
feature/cicd
feature/completion
feature/dist-nuget
feature/fix-ci-sdk-pypi-rubygem
feature/fix-clippy-on-stable-channel
feature/fix-deployment-script
feature/github-email
feature/gresiq-v1
feature/project-new-structure
feature/rsync-deploy
feature/ruby-runner
feature/sdk-npm
feature/sdk-workflows
feature/smbcloud-cli-release-npm
feature/smbcloud-deploy
feature/wasm
main
release/v0.7.4
| 1 | # MCP Registry |
| 2 | |
| 3 | The repository publishes two MCP servers to the [official MCP Registry](https://registry.modelcontextprotocol.io): |
| 4 | |
| 5 | - **`io.github.smbcloudXYZ/smbcloud-cli`** — the `smb --mcp` server for smbCloud projects, Mail, Auth, tenants, and deployments. |
| 6 | - **`io.github.smbcloudXYZ/xcrs`** — **XCRS Mobile & TV Automation**, available through `xcrs --mcp` or `smb --mcp --scope automation` for Xcode, ControlKit, CoreDevice, and adb workflows. |
| 7 | |
| 8 | The registry is a metadata index — it doesn't host binaries. The smbCloud |
| 9 | listing offers the hosted Streamable HTTP server as well as packages published |
| 10 | to npm and NuGet, while the standalone XCRS listing points at the `xcrs` crate |
| 11 | on crates.io. |
| 12 | |
| 13 | For running and configuring the server itself, see [MCP Server](./mcp.md). |
| 14 | |
| 15 | ## What makes up the listing |
| 16 | |
| 17 | | Piece | Where | |
| 18 | | --- | --- | |
| 19 | | smbCloud server metadata | [`server.json`](../server.json) at the repo root | |
| 20 | | XCRS server metadata | [`server-xcrs.json`](../server-xcrs.json) at the repo root | |
| 21 | | npm ownership proof | `mcpName` in the generated `@smbcloud/cli` `package.json` (`npm/scripts/render-main-package.cjs`) | |
| 22 | | NuGet ownership proof | `<!-- mcp-name: ... -->` in `nuget/smbcloud-cli/README.md` | |
| 23 | | Cargo ownership proof | Visible `mcp-name: ...` text in `crates/xcrs/README.md` | |
| 24 | | Publishing | `.github/workflows/release-mcp-registry.yml` | |
| 25 | |
| 26 | The registry checks each listed package for a marker naming the server. If the |
| 27 | marker is missing or doesn't match `name` in `server.json`, publishing fails |
| 28 | with "Registry validation failed for package". |
| 29 | |
| 30 | The markers ship *inside* the published artifacts, so they have to be in place |
| 31 | before the npm and NuGet packages are built — a version published before the |
| 32 | marker landed can never be listed, since neither registry lets you overwrite a |
| 33 | version. The publish workflow checks the real published artifacts (not just the |
| 34 | sources in this repo) and stops early if a marker is missing. |
| 35 | |
| 36 | ### Why the name is `io.github.smbcloudXYZ/...` |
| 37 | |
| 38 | The namespace has to match the authentication method. We authenticate with |
| 39 | GitHub OIDC from Actions, which grants the `io.github.smbcloudXYZ/*` namespace |
| 40 | (the reverse-DNS form of the `smbcloudXYZ` org). |
| 41 | |
| 42 | **The casing matters.** The registry grants the namespace with the org's exact |
| 43 | GitHub casing, and compares case-sensitively — `io.github.smbcloudxyz/...` is |
| 44 | rejected with a 403 even though GitHub itself treats org names |
| 45 | case-insensitively. Every marker has to use the same `smbcloudXYZ` spelling. |
| 46 | |
| 47 | Publishing under |
| 48 | `xyz.smbcloud/*` instead would mean domain-based auth: a `v=MCPv1` TXT record on |
| 49 | `smbcloud.xyz` plus an Ed25519 private key stored as a repo secret. OIDC needs |
| 50 | no secret at all, so that's what we use. |
| 51 | |
| 52 | ### Available connections |
| 53 | |
| 54 | - **Hosted** — Streamable HTTP at `https://api.smbcloud.xyz/v1/mcp`. |
| 55 | |
| 56 | - **npm** — `@smbcloud/cli`, launched as `npx @smbcloud/cli --mcp`. The package |
| 57 | declares a single binary (`smb`), so `npx` resolves it despite the name |
| 58 | difference. |
| 59 | - **NuGet** — `SmbCloud.Cli`, launched as `dnx SmbCloud.Cli --mcp`. |
| 60 | |
| 61 | PyPI is deliberately not listed. The `smbcloud-cli` wheel installs its |
| 62 | executable as `smb` (maturin `bindings = "bin"`), and `uvx smbcloud-cli` looks |
| 63 | for an executable matching the distribution name, so the launch command the |
| 64 | registry hands to clients wouldn't work. Adding PyPI would mean shipping an |
| 65 | extra console script named `smbcloud-cli`. Homebrew and the direct GitHub |
| 66 | release binaries have no registry package type at all; those install paths stay |
| 67 | documented in [Install](./cli-install.md). |
| 68 | |
| 69 | ## Releasing a new version |
| 70 | |
| 71 | Each server metadata file carries its version twice — once for the server, once |
| 72 | per package — and both are updated by `make patch | minor | major` along with |
| 73 | the rest of the release metadata (`scripts/sync-release-version.mjs`). |
| 74 | |
| 75 | Publishing is chained off the release: pushing a `v*` tag runs the crates.io |
| 76 | workflow, which fans out to the distribution workflows, and **NuGet CLI |
| 77 | Release** triggers **MCP Registry Release** once its publish job succeeds. It |
| 78 | hangs off NuGet rather than the fan-out because the listing needs both npm and |
| 79 | NuGet live at that version, and NuGet is the slower of the two. |
| 80 | |
| 81 | The registry fetches the package metadata during publish, so |
| 82 | `@smbcloud/cli@<version>` and `SmbCloud.Cli <version>` must already exist. npm |
| 83 | is queryable within seconds of publishing; nuget.org validates first and takes |
| 84 | roughly 5–15 minutes to reach the flat container. The workflow polls both for up |
| 85 | to ten minutes rather than failing on that gap. |
| 86 | |
| 87 | To publish by hand — a re-run after a transient failure, say — dispatch it with |
| 88 | the tag: |
| 89 | |
| 90 | ```sh |
| 91 | gh workflow run release-mcp-registry.yml -f tag=v0.4.13 |
| 92 | ``` |
| 93 | |
| 94 | Confirm both listings afterwards: |
| 95 | |
| 96 | ```sh |
| 97 | curl "https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.smbcloudXYZ/smbcloud-cli" |
| 98 | curl "https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.smbcloudXYZ/xcrs" |
| 99 | ``` |
| 100 | |
| 101 | ## Publishing by hand |
| 102 | |
| 103 | Rarely needed, but if Actions is unavailable: |
| 104 | |
| 105 | ```sh |
| 106 | brew install mcp-publisher |
| 107 | mcp-publisher login github # device flow, needs push access to smbcloudXYZ |
| 108 | mcp-publisher publish # reads ./server.json |
| 109 | ``` |
| 110 | |
| 111 | The release workflow publishes `server.json`, then temporarily swaps in |
| 112 | `server-xcrs.json` and publishes the standalone entry as well. Versions are |
| 113 | immutable — republishing the same version is rejected. Fixing a bad listing |
| 114 | means shipping a new patch version. |