Skip to main content
Glama

Keboola Explorer MCP Server

ci.yml8.58 kB
name: CI # How the CI Pipeline Works # - The CI workflow runs on all push events and pull requests. # - For pull requests from forks (coming from a different repository), we skip jobs/actions that need secrets (e.g., # publishing results, integration tests) to avoid exposing them. Only safe checks like local tests and flake8 are run. # - For pull requests from branches in this repository, the workflow is skipped to avoid running it twice (once for the # push and once for the PR). # - The full workflow (including jobs requiring secrets) runs only on pushes events to branches in this repository on: [ push, pull_request ] concurrency: ci-${{ github.ref }} permissions: contents: read checks: write jobs: build: name: Build, test and package # run this job only for push (avoiding pull requests from the same repo) or for pull requests from different repo if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository runs-on: ubuntu-latest strategy: matrix: python-version: ["3.10", "3.11", "3.12"] outputs: is_semantic_tag: ${{ steps.get_package_version.outputs.is_semantic_tag }} tag: ${{ steps.get_package_version.outputs.tag }} version: ${{ steps.get_package_version.outputs.version }} wheel_artifact_id: ${{ steps.wheel_artifact_upload.outputs.artifact-id }} steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip pip install uv uv sync --frozen --no-editable --extra dev # Runs tests with coverage and generates coverage.xml file and test-results.xml file # and checks flake8 code-style formatting that is compatible with isort & black # and verifies TOOLS.md is up-to-date with tool definitions # see setup in pyproject.toml - name: Unit tests, code style and documentation check run: | uv run tox - name: Publish test results uses: dorny/test-reporter@v1 # run this step even if a previous step failed, but only for push events or pull requests from the same repo if: (success() || failure()) && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) with: name: Test results (${{ matrix.python-version }}) path: ./test-results.xml reporter: 'java-junit' - name: Upload coverage to Codecov # run this step only for push events or pull requests from the same repo if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository uses: codecov/codecov-action@v4 with: file: ./coverage.xml fail_ci_if_error: true token: ${{ secrets.CODECOV_TOKEN }} - name: Build wheels package run: | uv build --wheel --no-sources - name: Get package version id: get_package_version if: matrix.python-version == '3.10' run: | VERSION=`uv run python3 -c 'import importlib.metadata; print(importlib.metadata.version("keboola_mcp_server"))'` TAG="${GITHUB_REF##*/}" IS_SEMANTIC_TAG=$(echo "$TAG" | grep -q '^v\?[0-9]\+\.[0-9]\+\.[0-9]\+$' && echo true || echo false) echo "Version = '$VERSION', Tag = '$TAG', is semantic tag = '$IS_SEMANTIC_TAG'" echo "is_semantic_tag=$IS_SEMANTIC_TAG" >> $GITHUB_OUTPUT echo "tag=$TAG" >> $GITHUB_OUTPUT echo "version=${VERSION}" >> $GITHUB_OUTPUT - name: Upload wheel package id: wheel_artifact_upload # run this step only for push events or pull requests from the same repo if: matrix.python-version == '3.10' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) uses: actions/upload-artifact@v4 with: name: keboola_mcp_server-${{ steps.get_package_version.outputs.version }}-py3-none-any.whl path: dist/keboola_mcp_server-${{ steps.get_package_version.outputs.version }}-py3-none-any.whl if-no-files-found: error compression-level: 0 # wheels are ZIP archives retention-days: 7 integration_tests: name: Integration Tests needs: build # run this job only for push events (not pull requests) if: github.event_name == 'push' runs-on: ubuntu-latest strategy: matrix: python-version: ["3.10", "3.11", "3.12"] # This ensures tests run sequentially, not in parallel max-parallel: 1 steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip pip install uv uv sync --frozen --no-editable --extra dev - name: Integration tests # run actual tests only for pushes to the same repository (not forks) if: github.repository == github.event.repository.full_name env: INTEGTEST_STORAGE_TOKEN: ${{ secrets.INTEGTEST_STORAGE_TOKEN }} INTEGTEST_STORAGE_API_URL: ${{ vars.INTEGTEST_STORAGE_API_URL }} INTEGTEST_WORKSPACE_SCHEMA: ${{ vars.INTEGTEST_WORKSPACE_SCHEMA }} run: | uv run tox -e integtests - name: Skip integration tests for forks # show a message when tests are skipped for forks if: github.repository != github.event.repository.full_name run: | echo "Integration tests skipped for fork repository" echo "Dependencies installed successfully - setup is working correctly" - name: Publish integration test results uses: dorny/test-reporter@v1 # publish results only when actual tests were run (same repository) if: (always()) && github.repository == github.event.repository.full_name with: name: Integration test results (${{ matrix.python-version }}) path: ./integtest-results.xml reporter: 'java-junit' deploy_to_pypi: name: Deploy to pypi.org needs: - build - integration_tests runs-on: ubuntu-latest if: | startsWith(github.ref, 'refs/tags/') && needs.build.outputs.is_semantic_tag == 'true' && needs.build.outputs.tag == format('v{0}', needs.build.outputs.version) steps: - name: Download wheel package uses: actions/download-artifact@v4 with: name: keboola_mcp_server-${{ needs.build.outputs.version }}-py3-none-any.whl path: dist/ - name: Publish package uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 with: user: __token__ password: ${{ secrets.PYPI_API_TOKEN }} register-with-anthropic: name: Register with Anthropic needs: - build - deploy_to_pypi runs-on: ubuntu-latest if: | startsWith(github.ref, 'refs/tags/') && needs.build.outputs.is_semantic_tag == 'true' && needs.build.outputs.tag == format('v{0}', needs.build.outputs.version) steps: - name: Checkout code uses: actions/checkout@v4 - name: Prepare server.json run: | sed 's/__MCP_SERVER_VERSION__/${{ needs.build.outputs.version }}/g' server.json.template > server.json cat server.json - name: Install mcp-publisher run: | PUBLISHER=1.2.3 curl -L "https://github.com/modelcontextprotocol/registry/releases/download/v${PUBLISHER}/mcp-publisher_${PUBLISHER}_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher sudo mv mcp-publisher /usr/local/bin/ - name: Create private key file run: | echo "${{ secrets.ANTHROPIC_REGISTRY_PVK }}" > key.pem chmod 600 key.pem - name: Register with Anthropic run: | set -euo pipefail mcp-publisher login dns --domain keboola.com --private-key $(openssl pkey -in key.pem -noout -text | grep -A3 "priv:" | tail -n +2 | tr -d ' :\n') mcp-publisher publish - name: Clean up private key if: always() run: | rm -f key.pem

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/keboola/keboola-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server