Repository navigation
feat(mcp): list the hosted MCP server in the MCP Registry at each release, and guard the tool annotations directories require - #4994
Merged
Conversation
… for Anthropic's Claude Connectors Directory flags any tool without a title or a readOnlyHint/destructiveHint annotation, and holds tool names to 64 characters. The test lists the tools the way a client does - tools/list through the MCP SDK's Client - and fails naming each tool that lacks a title, says nothing about being read-only, or writes without saying whether it is destructive. It also holds the read-only hint to the server's own read/write rule (RequestGate) and every delete tool to destructiveHint: true.
server.json lists OneUptime Cloud's MCP server in the MCP Registry (registry.modelcontextprotocol.io) as com.oneuptime/mcp: streamable HTTP at https://oneuptime.com/mcp, signed in to with OAuth, or given a project API key in the optional x-api-key header. It follows the registry's 2025-12-11 schema. Its version is a placeholder: the release publishes it at the release's own version. The test holds the entry to the server it describes - the route, the header the server reads an API key from, a client that leaves the header empty being asked to sign in, the source folder - and to the limits the registry checks only when a release publishes it.
…lease The publish-mcp-registry job runs Scripts/MCP/PublishToMcpRegistry.sh once finalize-github-release has published the release. The script publishes packages/App/FeatureSet/MCP/server.json as com.oneuptime/mcp at the release's version, and skips a version the registry already has, as Scripts/NPM/PublishAllPackages.sh does on npm. Only a clean 404 counts as not published: the registry is a preview service that answers a lookup with a 500 now and then, so any other answer is asked again and, if it persists, fails the job having published nothing. The registry lets only whoever controls oneuptime.com publish under com.oneuptime. GitHub's OIDC token cannot prove a domain, so the job signs in with an Ed25519 key whose public key is in a TXT record on oneuptime.com. The key is a secret of the mcp-registry-publish environment, which no other job names, and the job may only read the repository. It installs mcp-publisher 1.8.1 and checks the archive's sha256 before unpacking it. Until the TXT record and the secret exist, the job fails with a message that points at the setup steps in the MCP README.
Contributor
Author
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
This was referenced Oct 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Gets OneUptime Cloud's MCP server ready for MCP directories, starting with the official MCP Registry. Nothing is published or submitted by this PR.
What changes
packages/App/FeatureSet/MCP/server.json: the registry entry,com.oneuptime/mcp, on the registry's current schema (2025-12-11). One remote: streamable HTTP athttps://oneuptime.com/mcp. Clients sign in with OAuth, or send a project API key in the optional, secretx-api-keyheader. A client that leaves the header empty gets the normal sign-in challenge. The entry also carries the title, description, docs URL, repository (with its folder) and the app icon. Itsversionis a0.0.0placeholder, which the release replaces, ashelm package --versiondoes for the charts.publish-mcp-registryjob inrelease.yml, runningScripts/MCP/PublishToMcpRegistry.sh: afterfinalize-github-release, it publishes server.json at the release's version.Scripts/NPM/PublishAllPackages.shskips versions npm has, so a re-run publishes nothing twice.mcp-publisher1.8.1, pinned by the archive's sha256 (checked against the release's checksums file).ToolAnnotationsForDirectories.test.ts: lists the tools the way a client does (tools/listthrough the MCP SDK'sClient). It fails, naming the tool, when any of the 193 tools:title;readOnlyHint;destructiveHint.It also checks three more things: the read-only hint agrees with what
RequestGatelets a read-only sign-in call, every delete tool is destructive, and names are at most 64 characters, the Claude Connectors Directory's other per-tool rule. All of this holds today. I also ran it against deliberately broken tools to confirm it fails.Tests for the rest:
RegistryServerJson.test.tschecks the entry against the server, andTests/Ops/McpRegistryRelease.test.jsruns the script with a fakecurlandmcp-publisherand checks the job's shape. The MCP README and the Ops README document them.Why DNS instead of GitHub OIDC
The name
com.oneuptime/mcpwas chosen so the name matches the domain of the URL it lists. GitHub's OIDC token can only proveio.github.<owner>/*. So the job signs in withmcp-publisher login dnsand an Ed25519 key whose public key sits in a TXT record ononeuptime.com. The key is a secret of themcp-registry-publishenvironment, and no other job names that environment.Before the next release
The job fails (publishing nothing, blocking nothing: no job waits for it) until these exist. The MCP README has the commands:
oneuptime.com:v=MCPv1; k=ed25519; p=<public key>.mcp-registry-publish, limited to thereleasebranch, with the secretMCP_REGISTRY_PRIVATE_KEY(the private key in hex).Not changed here
update_*tools are annotateddestructiveHint: false. Anthropic's review criteria ask fordestructiveHint: trueon tools that "modify or delete data". ChatGPT's app guidelines call overwriting destructive, and also want explicitdestructiveHintandopenWorldHinton every tool. Changing this is a product decision:MCP_ALLOW_DESTRUCTIVE=falsewould then drop the update tools.Tests
packages/App: the wholeFeatureSet/MCP/Testsfolder, andnpm run compile.Tests/Ops: the new suite, and every suite that readsrelease.yml(ReleaseE2ePipeline, ReleaseCriticalPath, GomplateSetupCoverage and the rest): 15 suites.server.jsonwas validated against the published 2025-12-11 JSON schema.