diff --git a/.github/workflows/release-mcp-registry.yml b/.github/workflows/release-mcp-registry.yml new file mode 100644 index 0000000..61d0e58 --- /dev/null +++ b/.github/workflows/release-mcp-registry.yml @@ -0,0 +1,79 @@ +name: MCP Registry Release + +on: + workflow_dispatch: + inputs: + version: + description: "Override the version in server.json (e.g. 0.2.0); leave blank to publish as-is" + required: false + +# A remote server proves namespace ownership through domain (DNS) verification, +# not GitHub OIDC: the registry checks a v=MCPv1 TXT record on sigit.si against +# a request signed with the matching Ed25519 private key. See the MCP Registry +# doc in the sigit-si repo for the one-time key/DNS setup. +permissions: + contents: read + +jobs: + publish: + name: Publish server.json to the MCP Registry + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Optionally override the version in server.json + shell: bash + run: | + version="${{ github.event.inputs.version }}" + if [ -n "${version}" ]; then + jq --arg v "${version}" '.version = $v' server.json > server.tmp + mv server.tmp server.json + fi + cat server.json + + - name: Check the remote URL matches the namespace domain + shell: bash + run: | + # The registry rejects a remote server whose URL isn't under the + # namespace's domain. si.sigit -> sigit.si, so every listed remote + # must live on sigit.si (or a subdomain). + server_name="$(jq -r '.name' server.json)" + domain="$(echo "${server_name%%/*}" | awk -F. '{ for (i=NF; i>=1; i--) printf "%s%s", $i, (i>1 ? "." : "") }')" + echo "Server: ${server_name} Domain: ${domain}" + + bad="$(jq -r --arg d "${domain}" ' + .remotes // [] + | map(.url | sub("^[a-z]+://"; "") | sub("/.*$"; "")) + | map(select(. != $d and (endswith("." + $d) | not))) + | .[]' server.json)" + if [ -n "${bad}" ]; then + echo "Remote URL host(s) not under ${domain}: ${bad}" >&2 + exit 1 + fi + + - name: Install mcp-publisher + shell: bash + run: | + curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher + + - name: Authenticate to the MCP Registry + shell: bash + env: + MCP_REGISTRY_DNS_PRIVATE_KEY: ${{ secrets.MCP_REGISTRY_DNS_PRIVATE_KEY }} + run: | + if [ -z "${MCP_REGISTRY_DNS_PRIVATE_KEY}" ]; then + echo "MCP_REGISTRY_DNS_PRIVATE_KEY secret is not set. See the MCP Registry doc in the sigit-si repo." >&2 + exit 1 + fi + ./mcp-publisher login dns --domain=sigit.si --private-key="${MCP_REGISTRY_DNS_PRIVATE_KEY}" + + - name: Publish + shell: bash + run: ./mcp-publisher publish + + - name: Verify the server is listed + shell: bash + run: | + server_name="$(jq -r '.name' server.json)" + curl -fsSL "https://registry.modelcontextprotocol.io/v0.1/servers?search=${server_name}" | jq . diff --git a/README.md b/README.md index 710208c..ebf6cd5 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,17 @@ they're served over the same MCP (Model Context Protocol) JSON-RPC endpoint the AI agent uses. `sigit-si-api` speaks that transport internally; it's not visible at the call site. +## MCP Registry listing + +The sigit.si MCP server (the same endpoint `sigit-si-api` talks to, and the +official MCP server the siGit Code CLI bakes in) is published to the +[official MCP Registry](https://registry.modelcontextprotocol.io) as +**`si.sigit/sigit`**, a remote Streamable-HTTP listing, so registry-aware +clients can add it in one click. `server.json` at the repo root and the +`release-mcp-registry.yml` workflow own that listing; namespace ownership is +proven by a DNS TXT record on `sigit.si`. The internal setup and release +runbook live with the server (private `sigit-si` repo). + ## Development ```sh diff --git a/server.json b/server.json new file mode 100644 index 0000000..d093554 --- /dev/null +++ b/server.json @@ -0,0 +1,39 @@ +{ + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json", + "name": "si.sigit/sigit", + "title": "siGit", + "description": "MCP server for siGit (sigit.si): browse repos, search code, manage PRs/issues, web search.", + "version": "1.2.5", + "websiteUrl": "https://sigit.si", + "repository": { + "url": "https://github.com/getsigit/si", + "source": "github" + }, + "remotes": [ + { + "type": "streamable-http", + "url": "https://sigit.si/api/v1/mcp" + } + ], + "_meta": { + "io.modelcontextprotocol.registry/publisher-provided": { + "categories": ["developer-tools", "version-control", "ai-agents"], + "keywords": [ + "git", + "git hosting", + "mcp server", + "model context protocol", + "code search", + "pull requests", + "issues", + "repositories", + "web search", + "coding agent", + "ai coding agent", + "ai agent tools", + "developer tools", + "software development" + ] + } + } +}