diff --git a/.github/workflows/publish-mcp-registry.yml b/.github/workflows/publish-mcp-registry.yml new file mode 100644 index 0000000..a8a21b8 --- /dev/null +++ b/.github/workflows/publish-mcp-registry.yml @@ -0,0 +1,79 @@ +name: Publish MCP Registry + +on: + push: + branches: [ main ] + paths: + - server.json + workflow_dispatch: + +concurrency: + group: publish-mcp-registry + cancel-in-progress: false + +jobs: + publish: + if: github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + + steps: + - name: Check out repository + uses: actions/checkout@v5 + + - name: Check registry version alignment + run: | + PROJECT_VERSION="$(python3 -c 'import tomllib; print(tomllib.load(open("pyproject.toml", "rb"))["project"]["version"])')" + REGISTRY_VERSION="$(jq -r '.version' server.json)" + if [[ "${PROJECT_VERSION}" != "${REGISTRY_VERSION}" ]]; then + echo "::error title=Version mismatch::pyproject.toml is ${PROJECT_VERSION}, but server.json is ${REGISTRY_VERSION}. Keep both versions aligned." + exit 1 + fi + + # Registry versions are immutable. Every server.json metadata update must + # use a version that has not previously been published. + - name: Check registry version is unpublished + run: | + SERVER_NAME="$(jq -r '.name' server.json)" + SERVER_VERSION="$(jq -r '.version' server.json)" + ENCODED_NAME="$(jq -rn --arg value "${SERVER_NAME}" '$value | @uri')" + ENCODED_VERSION="$(jq -rn --arg value "${SERVER_VERSION}" '$value | @uri')" + REGISTRY_URL="https://registry.modelcontextprotocol.io/v0.1/servers/${ENCODED_NAME}/versions/${ENCODED_VERSION}" + HTTP_STATUS="$(curl --silent --show-error --location \ + --output registry-version.json \ + --write-out '%{http_code}' \ + "${REGISTRY_URL}")" + + case "${HTTP_STATUS}" in + 404) + ;; + 200) + echo "::error title=Registry version already exists::${SERVER_NAME} ${SERVER_VERSION} is already published. Bump version in server.json and pyproject.toml before publishing metadata changes." + exit 1 + ;; + *) + echo "::error title=Registry lookup failed::The registry returned HTTP ${HTTP_STATUS} while checking ${SERVER_NAME} ${SERVER_VERSION}." + cat registry-version.json + exit 1 + ;; + esac + + - name: Install MCP publisher + env: + MCP_PUBLISHER_VERSION: v1.8.1 + MCP_PUBLISHER_SHA256: a06c9096dcb9727c13555b6be26c7effa707b01f06a4c561ba7a3635443cf2cc + run: | + curl --fail --location --silent --show-error \ + --output mcp-publisher.tar.gz \ + "https://github.com/modelcontextprotocol/registry/releases/download/${MCP_PUBLISHER_VERSION}/mcp-publisher_linux_amd64.tar.gz" + echo "${MCP_PUBLISHER_SHA256} mcp-publisher.tar.gz" | sha256sum --check - + tar -xzf mcp-publisher.tar.gz mcp-publisher + chmod +x mcp-publisher + + - name: Authenticate to MCP Registry + run: ./mcp-publisher login github-oidc + + - name: Publish server metadata + run: ./mcp-publisher publish server.json diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8488255..9dd8f1e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -30,5 +30,14 @@ jobs: - name: Install dependencies run: uv sync --group dev --frozen + - name: Check registry version alignment + run: | + PROJECT_VERSION="$(uv run --no-sync python -c 'import tomllib; print(tomllib.load(open("pyproject.toml", "rb"))["project"]["version"])')" + REGISTRY_VERSION="$(jq -r '.version' server.json)" + if [[ "${PROJECT_VERSION}" != "${REGISTRY_VERSION}" ]]; then + echo "::error title=Version mismatch::pyproject.toml is ${PROJECT_VERSION}, but server.json is ${REGISTRY_VERSION}. Keep both versions aligned." + exit 1 + fi + - name: Run tests run: uv run pytest -q diff --git a/pyproject.toml b/pyproject.toml index 23fe7a9..9a6a9fe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "serpapi-mcp-server" -version = "0.6.0" +version = "1.0.2" description = "A Model Context Protocol (MCP) server implementation that integrates with SerpApi for comprehensive search engine results and data extraction" requires-python = ">=3.12" dependencies = [ diff --git a/server.json b/server.json index e9d06c3..dabd494 100644 --- a/server.json +++ b/server.json @@ -1,16 +1,26 @@ { "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json", "name": "io.github.serpapi/serpapi-mcp", - "version": "1.0.1", + "title": "SerpApi", + "version": "1.0.2", "description": "Official SerpApi MCP server for Google, Bing, and other search engines.", + "websiteUrl": "https://serpapi.com/", "repository": { "url": "https://github.com/serpapi/serpapi-mcp", "source": "github" }, "remotes": [ { - "type": "http", - "url": "https://mcp.serpapi.com/mcp" + "type": "streamable-http", + "url": "https://mcp.serpapi.com/{SERPAPI_API_KEY}/mcp", + "variables": { + "SERPAPI_API_KEY": { + "description": "Your SerpApi API key. Get one at https://serpapi.com/manage-api-key", + "isRequired": true, + "isSecret": true, + "placeholder": "your-serpapi-api-key" + } + } } ] -} \ No newline at end of file +} diff --git a/uv.lock b/uv.lock index 553e7f8..8bec5eb 100644 --- a/uv.lock +++ b/uv.lock @@ -1389,7 +1389,7 @@ wheels = [ [[package]] name = "serpapi-mcp-server" -version = "0.6.0" +version = "1.0.2" source = { virtual = "." } dependencies = [ { name = "beautifulsoup4" },