Skip to main content
Glama

Sequential Story MCP Server

by dhkts1
name: CI on: push: branches: [main] pull_request: branches: [main] # Only run this workflow when ENABLE_BADGES is set to 'true' in repository variables jobs: check-if-enabled: runs-on: ubuntu-latest outputs: enabled: ${{ steps.check.outputs.enabled }} steps: - id: check run: | if [[ "${ENABLE_BADGES:-${{ vars.ENABLE_BADGES }}}" == "true" ]]; then echo "enabled=true" >> "$GITHUB_OUTPUT" else echo "enabled=false" >> "$GITHUB_OUTPUT" echo "::notice::Badges workflow is disabled. Set ENABLE_BADGES repository variable to 'true' to enable it." fi # Run checks on pull requests without generating badges checks-only: if: github.event_name == 'pull_request' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install uv uses: astral-sh/setup-uv@v5 with: enable-cache: true cache-dependency-glob: "pyproject.toml" - name: Set up Python id: setup-python uses: actions/setup-python@v5 with: python-version-file: "pyproject.toml" - name: Install dependencies run: uv sync --all-extras --dev # Cache pre-commit hooks - name: Cache pre-commit hooks uses: actions/cache@v4 with: path: ~/.cache/pre-commit key: ${{ runner.os }}-precommit-${{ hashFiles('.pre-commit-config.yaml') }} restore-keys: | ${{ runner.os }}-precommit- # Run pre-commit hooks - name: Run pre-commit hooks id: pre-commit run: uv run pre-commit run --all-files # Run checks and generate badges only on push to main checks-and-badges: needs: check-if-enabled if: needs.check-if-enabled.outputs.enabled == 'true' && github.event_name == 'push' && github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install uv uses: astral-sh/setup-uv@v5 with: enable-cache: true cache-dependency-glob: "pyproject.toml" - name: Set up Python id: setup-python uses: actions/setup-python@v5 with: python-version-file: "pyproject.toml" - name: Check Python dependencies run: uv lock --check - name: Install dependencies run: uv sync --all-extras --dev # Cache pre-commit hooks - name: Cache pre-commit hooks uses: actions/cache@v4 with: path: ~/.cache/pre-commit key: ${{ runner.os }}-precommit-${{ hashFiles('.pre-commit-config.yaml') }} restore-keys: | ${{ runner.os }}-precommit- # Run pre-commit hooks and capture status - name: Run pre-commit hooks id: pre-commit run: uv run pre-commit run --all-files - name: Set pre-commit status run: | if [ "${{ steps.pre-commit.outcome }}" == 'success' ]; then { echo "PRE_COMMIT_STATUS=passing" echo "PRE_COMMIT_COLOR=green" } >> "$GITHUB_ENV" else # Count failed hooks FAILED_HOOKS=$(echo "${{ steps.pre-commit.outputs.stdout }}" | grep -c "Failed" || echo "0") if [ "$FAILED_HOOKS" -gt 0 ]; then { echo "PRE_COMMIT_STATUS=failing ($FAILED_HOOKS issues)" echo "PRE_COMMIT_COLOR=red" } >> "$GITHUB_ENV" else { echo "PRE_COMMIT_STATUS=failing" echo "PRE_COMMIT_COLOR=red" } >> "$GITHUB_ENV" fi fi # Extract individual check statuses for badges - name: Run Ruff check id: ruff run: uv run poe ruff-check - name: Run Ruff format id: ruff-format run: uv run poe ruff-format - name: Set Ruff status run: | if [ "${{ steps.ruff.outcome }}" == 'success' ]; then { echo "RUFF_STATUS=passing (0 issues)" echo "RUFF_COLOR=green" } >> "$GITHUB_ENV" else # Try to extract the number of issues ISSUES=$(echo "${{ steps.ruff.outputs.stderr }}" | grep -o "Found [0-9]\\+ error" | grep -o "[0-9]\\+" || echo "") if [ -n "$ISSUES" ]; then { echo "RUFF_STATUS=failing ($ISSUES issues)" echo "RUFF_COLOR=red" } >> "$GITHUB_ENV" else { echo "RUFF_STATUS=failing" echo "RUFF_COLOR=red" } >> "$GITHUB_ENV" fi fi - name: Run Pyright id: pyright run: uv run poe pyright - name: Set Pyright status run: | if [ "${{ steps.pyright.outcome }}" == 'success' ]; then { echo "PYRIGHT_STATUS=passing (0 errors)" echo "PYRIGHT_COLOR=green" } >> "$GITHUB_ENV" else # Try to extract the number of errors ERRORS=$(echo "${{ steps.pyright.outputs.stderr }}" | grep -o "[0-9]\\+ error" | grep -o "[0-9]\\+" || echo "") if [ -n "$ERRORS" ]; then { echo "PYRIGHT_STATUS=failing ($ERRORS errors)" echo "PYRIGHT_COLOR=red" } >> "$GITHUB_ENV" else { echo "PYRIGHT_STATUS=failing" echo "PYRIGHT_COLOR=red" } >> "$GITHUB_ENV" fi fi - name: Run Vulture id: vulture run: uv run poe vulture - name: Set Vulture status run: | VULTURE_OUTPUT="${{ steps.vulture.outputs.stdout }}" if [[ "${{ steps.vulture.outcome }}" == 'success' ]]; then { echo "VULTURE_STATUS=0% dead code" echo "VULTURE_COLOR=green" } >> "$GITHUB_ENV" else # Try to extract percentage if available UNUSED_CODE=$(echo "$VULTURE_OUTPUT" | grep -o '[0-9]\+% confidence' | head -1 | grep -o '[0-9]\+' || echo "") if [ -n "$UNUSED_CODE" ]; then { echo "VULTURE_STATUS=$UNUSED_CODE% dead code" if [ "$UNUSED_CODE" -gt 10 ]; then echo "VULTURE_COLOR=red" elif [ "$UNUSED_CODE" -gt 5 ]; then echo "VULTURE_COLOR=yellow" else echo "VULTURE_COLOR=green" fi } >> "$GITHUB_ENV" else { echo "VULTURE_STATUS=failing" echo "VULTURE_COLOR=red" } >> "$GITHUB_ENV" fi fi # Run tests with coverage - name: Run tests with coverage id: coverage run: uv run poe test-coverage - name: Extract coverage data run: | if [ -f coverage.xml ]; then COVERAGE=$(python -c "import xml.etree.ElementTree as ET; print(ET.parse('coverage.xml').getroot().get('line-rate'))") COVERAGE_PCT=$(python -c "print(f'{float(\"$COVERAGE\")*100:.2f}%')") # Convert to numeric for comparison - fix the extraction to get the correct number COVERAGE_NUM=$(python -c "print(int(float('$COVERAGE')*100))") # Debug output echo "Debug: COVERAGE=$COVERAGE" echo "Debug: COVERAGE_PCT=$COVERAGE_PCT" echo "Debug: COVERAGE_NUM=$COVERAGE_NUM" { echo "COVERAGE=$COVERAGE_PCT" if [ "$COVERAGE_NUM" -lt 50 ]; then echo "COVERAGE_COLOR=red" echo "COVERAGE_DESCRIPTION=insufficient" elif [ "$COVERAGE_NUM" -lt 65 ]; then echo "COVERAGE_COLOR=yellow" echo "COVERAGE_DESCRIPTION=partial" elif [ "$COVERAGE_NUM" -lt 85 ]; then echo "COVERAGE_COLOR=green" echo "COVERAGE_DESCRIPTION=good" else echo "COVERAGE_COLOR=brightgreen" echo "COVERAGE_DESCRIPTION=excellent" fi } >> "$GITHUB_ENV" else { echo "COVERAGE=unknown" echo "COVERAGE_COLOR=red" echo "COVERAGE_DESCRIPTION=missing" } >> "$GITHUB_ENV" fi # Run bandit security check - name: Run Bandit id: bandit run: uv run poe bandit - name: Set Bandit status run: | if [ "${{ steps.bandit.outcome }}" == 'success' ]; then { echo "BANDIT_STATUS=secure (0 issues)" echo "BANDIT_COLOR=green" } >> "$GITHUB_ENV" else # Try to extract the number of issues ISSUES=$(echo "${{ steps.bandit.outputs.stdout }}" | grep -o "Issue: [0-9]\\+" | wc -l || echo "") if [ -n "$ISSUES" ] && [ "$ISSUES" -gt 0 ]; then { echo "BANDIT_STATUS=issues found ($ISSUES)" echo "BANDIT_COLOR=red" } >> "$GITHUB_ENV" else { echo "BANDIT_STATUS=issues found" echo "BANDIT_COLOR=red" } >> "$GITHUB_ENV" fi fi # Run interrogate for docstring coverage - name: Run Interrogate id: interrogate run: uv run poe interrogate - name: Set Interrogate status run: | if [ "${{ steps.interrogate.outcome }}" == 'success' ]; then # Try to extract the coverage percentage DOCS_COVERAGE=$(echo "${{ steps.interrogate.outputs.stdout }}" | grep -o '[0-9]\+\.[0-9]\+%' | head -1 || echo "") if [ -n "$DOCS_COVERAGE" ]; then # Try to extract the number of missing docstrings MISSING=$(echo "${{ steps.interrogate.outputs.stdout }}" | grep -o 'missing [0-9]\+ docstring' | grep -o '[0-9]\+' || echo "") # Extract numeric value for comparison DOCS_NUM=$(echo "$DOCS_COVERAGE" | sed 's/%//' | sed 's/\..*//') { if [ -n "$MISSING" ]; then echo "INTERROGATE_STATUS=$DOCS_COVERAGE ($MISSING missing)" else echo "INTERROGATE_STATUS=$DOCS_COVERAGE" fi if [ "$DOCS_NUM" -lt 60 ]; then echo "INTERROGATE_COLOR=red" elif [ "$DOCS_NUM" -lt 80 ]; then echo "INTERROGATE_COLOR=yellow" else echo "INTERROGATE_COLOR=green" fi } >> "$GITHUB_ENV" else { echo "INTERROGATE_STATUS=passing (100%)" echo "INTERROGATE_COLOR=green" } >> "$GITHUB_ENV" fi else { echo "INTERROGATE_STATUS=failing" echo "INTERROGATE_COLOR=red" } >> "$GITHUB_ENV" fi # Run radon for code complexity - name: Run Radon id: radon run: uv run poe radon - name: Set Radon status run: | if [ "${{ steps.radon.outcome }}" == 'success' ]; then # Try to extract the average complexity COMPLEXITY=$(echo "${{ steps.radon.outputs.stdout }}" | grep -o 'Average complexity: [A-F]' | cut -d' ' -f3 || echo "") if [ -n "$COMPLEXITY" ]; then # Try to extract the actual complexity value COMPLEXITY_VALUE=$(echo "${{ steps.radon.outputs.stdout }}" | grep -o 'Average complexity: [0-9.]\+' | cut -d' ' -f3 || echo "") { if [ -n "$COMPLEXITY_VALUE" ]; then echo "RADON_STATUS=Grade $COMPLEXITY ($COMPLEXITY_VALUE)" else echo "RADON_STATUS=Grade $COMPLEXITY" fi if [ "$COMPLEXITY" = "A" ] || [ "$COMPLEXITY" = "B" ]; then echo "RADON_COLOR=green" elif [ "$COMPLEXITY" = "C" ]; then echo "RADON_COLOR=yellow" else echo "RADON_COLOR=red" fi } >> "$GITHUB_ENV" else { echo "RADON_STATUS=passing" echo "RADON_COLOR=green" } >> "$GITHUB_ENV" fi else { echo "RADON_STATUS=failing" echo "RADON_COLOR=red" } >> "$GITHUB_ENV" fi # Run xenon for code maintainability - name: Run Xenon id: xenon run: uv run poe xenon - name: Set Xenon status run: | if [ "${{ steps.xenon.outcome }}" == 'success' ]; then # Try to extract metrics if available RANK=$(echo "${{ steps.xenon.outputs.stdout }}" | grep -o 'Rank: [A-F]' | cut -d' ' -f2 || echo "") if [ -n "$RANK" ]; then { echo "XENON_STATUS=Grade $RANK" if [ "$RANK" = "A" ] || [ "$RANK" = "B" ]; then echo "XENON_COLOR=green" elif [ "$RANK" = "C" ]; then echo "XENON_COLOR=yellow" else echo "XENON_COLOR=red" fi } >> "$GITHUB_ENV" else { echo "XENON_STATUS=maintainable" echo "XENON_COLOR=green" } >> "$GITHUB_ENV" fi else { echo "XENON_STATUS=needs refactoring" echo "XENON_COLOR=red" } >> "$GITHUB_ENV" fi # Create a single JSON file with all badge data - name: Prepare badge data run: | cat > badges.json << EOF { "schemaVersion": 1, "badges": [ { "label": "pre-commit", "message": "${{ env.PRE_COMMIT_STATUS }}", "color": "${{ env.PRE_COMMIT_COLOR }}", "namedLogo": "github", "description": "Pre-commit hooks status" }, { "label": "coverage", "message": "${{ env.COVERAGE }} (${{ env.COVERAGE_DESCRIPTION }})", "color": "${{ env.COVERAGE_COLOR }}", "namedLogo": "pytest", "description": "Test coverage percentage" }, { "label": "ruff", "message": "${{ env.RUFF_STATUS }}", "color": "${{ env.RUFF_COLOR }}", "namedLogo": "ruff", "description": "Ruff linting status" }, { "label": "typing", "message": "${{ env.PYRIGHT_STATUS }}", "color": "${{ env.PYRIGHT_COLOR }}", "namedLogo": "python", "description": "Pyright type checking status" }, { "label": "dead code", "message": "${{ env.VULTURE_STATUS }}", "color": "${{ env.VULTURE_COLOR }}", "namedLogo": "python", "description": "Vulture dead code detection" }, { "label": "security", "message": "${{ env.BANDIT_STATUS }}", "color": "${{ env.BANDIT_COLOR }}", "namedLogo": "shieldsdotio", "description": "Bandit security check status" }, { "label": "docs", "message": "${{ env.INTERROGATE_STATUS }}", "color": "${{ env.INTERROGATE_COLOR }}", "namedLogo": "readthedocs", "description": "Interrogate docstring coverage" }, { "label": "complexity", "message": "${{ env.RADON_STATUS }}", "color": "${{ env.RADON_COLOR }}", "namedLogo": "codacy", "description": "Radon code complexity rating" }, { "label": "maintainability", "message": "${{ env.XENON_STATUS }}", "color": "${{ env.XENON_COLOR }}", "namedLogo": "codeclimate", "description": "Xenon code maintainability status" } ] } EOF # Update the single Gist file with all badge data - name: Update Badges Gist uses: exuanbo/actions-deploy-gist@v1 with: token: ${{ secrets.BADGES_TOKEN }} gist_id: ${{ secrets.BADGES_GIST_ID }} file_path: badges.json file_type: text # Fail the workflow if pre-commit failed - name: Check for failures if: steps.pre-commit.outcome != 'success' run: exit 1

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/dhkts1/sequentialStory'

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