development
md 109 lines 4.96 KB
Rendered Raw
1 # MCP Registry
2
3 The Onde CLI's MCP server (`onde --mcp`, added in v0.4.0) is listed in the
4 [official MCP Registry](https://registry.modelcontextprotocol.io) as
5 **`io.github.ondeinference/onde-cli`**. The registry is a metadata index — it
6 doesn't host binaries — so the listing points at packages we already publish to
7 npm and NuGet, and clients that browse the registry can offer a one-click
8 install.
9
10 ## What makes up the listing
11
12 | Piece | Where |
13 | --- | --- |
14 | Server metadata | [`server.json`](../server.json) at the repo root |
15 | npm ownership proof | `mcpName` in `npm/package-main.json.tmpl`, copied verbatim into the published manifest by `npm/scripts/render-main-package.cjs` |
16 | NuGet ownership proof | `<!-- mcp-name: ... -->` in `nuget/onde-cli/README.md` |
17 | Publishing | `.github/workflows/release-mcp-registry.yml` |
18
19 The registry checks each listed package for a marker naming the server. If the
20 marker is missing or doesn't match `name` in `server.json`, publishing fails
21 with "Registry validation failed for package".
22
23 The markers ship *inside* the published artifacts, so they have to be in place
24 before the npm and NuGet packages are built. A version published before the
25 marker landed can never be listed, since neither registry lets you overwrite a
26 version. The publish workflow checks the real published artifacts, not just the
27 sources in this repo, and stops early if a marker is missing.
28
29 **v0.4.0 cannot be listed.** It shipped the MCP server, and its NuGet package
30 carries the `mcp-name` marker, but `@ondeinference/cli@0.4.0` published without
31 `mcpName` — the template change adding it came afterwards. `server.json`
32 therefore targets 0.4.1, the first release where both markers are live.
33
34 ### Why the name is `io.github.ondeinference/...`
35
36 The namespace has to match the authentication method. We authenticate with
37 GitHub OIDC from Actions, which grants the `io.github.ondeinference/*` namespace
38 (the reverse-DNS form of the `ondeinference` org).
39
40 The registry grants the namespace with the org's exact GitHub casing and
41 compares case-sensitively, so a mis-cased namespace is rejected with a 403 even
42 though GitHub itself treats org names case-insensitively. The `ondeinference`
43 org is all lowercase, which makes this a non-issue here — but every marker still
44 has to spell it identically.
45
46 ### Which packages are listed
47
48 - **npm** — `@ondeinference/cli`, launched as `npx @ondeinference/cli --mcp`.
49 The package declares a single binary (`onde`), so `npx` resolves it despite
50 the name difference.
51 - **NuGet** — `Onde.Cli`, launched as `dnx Onde.Cli --mcp`.
52
53 PyPI is deliberately not listed. The `onde-cli` wheel installs its executable as
54 `onde` (maturin `bindings = "bin"`), and `uvx onde-cli` looks for an executable
55 matching the distribution name, so the launch command the registry hands to
56 clients wouldn't work. Adding PyPI would mean shipping an extra console script
57 named `onde-cli`. pub.dev, Homebrew, and the direct GitHub release binaries have
58 no registry package type at all.
59
60 ## Releasing a new version
61
62 `server.json` carries the version twice, once for the server and once per
63 package. The publish workflow rewrites both from the tag it was given, so the
64 committed values are documentation rather than the source of truth — keep them
65 pointing at the next intended listing.
66
67 Publishing is chained off the release: pushing a `v*` tag runs the crates.io
68 workflow, which fans out to the distribution workflows, and **NuGet Release**
69 triggers **MCP Registry Release** once its publish job succeeds. It hangs off
70 NuGet rather than the fan-out because the listing needs both npm and NuGet live
71 at that version, and NuGet is the slower of the two — in the v0.4.0 release,
72 NuGet took 55 minutes against npm's 35.
73
74 The registry fetches the package metadata during publish, so
75 `@ondeinference/cli@<version>` and `Onde.Cli <version>` must already exist. npm
76 is queryable within seconds of publishing; nuget.org validates first and takes
77 roughly 5–15 minutes to reach the flat container. The workflow polls both for up
78 to ten minutes rather than failing on that gap.
79
80 To publish by hand — a re-run after a transient failure, say — dispatch it with
81 the tag:
82
83 ```sh
84 gh workflow run release-mcp-registry.yml --ref main -f tag=v0.4.1
85 ```
86
87 The workflow publishes the `server.json` on the branch you dispatch from, not
88 the one at the tag. It uploads metadata rather than building from source, and
89 that metadata can change after a tag is cut; the tag input only selects which
90 version to publish.
91
92 Confirm the listing afterwards:
93
94 ```sh
95 curl "https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.ondeinference/onde-cli"
96 ```
97
98 ## Publishing without Actions
99
100 Rarely needed, but if Actions is unavailable:
101
102 ```sh
103 brew install mcp-publisher
104 mcp-publisher login github # device flow, needs push access to ondeinference
105 mcp-publisher publish # reads ./server.json
106 ```
107
108 Versions are immutable — republishing the same version is rejected. Fixing a bad
109 listing means shipping a new patch version.