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 **CLI Release NuGet**
77 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.