Skip to main content
Glama

Actions Check

CI npm downloads OpenSSF Scorecard License: MIT

Coding agents write GitHub Actions workflows from memory, so they reach for actions/checkout@v3, echo "::set-output ..." and runs-on: ubuntu-20.04 years after those stopped being current, and they paste untrusted pull request titles into shell scripts. Actions Check reviews workflow files the way a careful maintainer would, and says what to change:

  • Every action against its latest release, from the action's own git tags (no API limit): how far behind it is, the runtime it runs on (Node 16 actions are deprecated), and the exact line to pin it by commit SHA (actions/checkout@<sha> # v7.0.1). A moving tag like @v3 names the release it actually points at.

  • Runners against GitHub's runner-images list, matrix values included: labels GitHub no longer provides (jobs wait and fail) and deprecated ones.

  • Security: untrusted event text (issue and pull request titles, bodies, branch names) expanded into run: scripts, pull_request_target workflows that check out the pull request's code, third-party actions not pinned to a commit, missing permissions.

  • Deprecated commands: set-output, save-state, set-env, add-path.

Every finding has the file, the line and a fix. No key needed.

Built and maintained by Arhan Canli.

Install

Install in Cursor Install in VS Code Install in Goose

Needs Node.js 20 or newer. No account or key.

Claude Code

claude mcp add actions-check -- npx -y actions-check-mcp

Claude Desktop: download actions-check-mcp-<version>.mcpb from the latest release and open it. The bundle is signed; verify it with gh attestation verify <file> --repo arhancanli/actions-check-mcp.

Any other client (Windsurf, Zed, Cline, Continue and others), in its MCP config file:

{
  "mcpServers": {
    "actions-check": {
      "command": "npx",
      "args": [
        "-y",
        "actions-check-mcp"
      ]
    }
  }
}

Docker

docker build -t actions-check-mcp https://github.com/arhancanli/actions-check-mcp.git && docker run -i --rm actions-check-mcp

Hosted (Streamable HTTP): node src/server.mjs --http serves stateless MCP at POST /mcp (port from PORT, default 3000).

Related MCP server: TaskBounty Check

Example

An agent calls check_workflows with:

{
  "files": [
    {
      "path": ".github/workflows/ci.yml",
      "content": "name: CI\non:\n  pull_request_target:\n  push:\njobs:\n  build:\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        os: [ubuntu-20.04, ubuntu-latest, macos-14]\n    steps:\n      - uses: actions/checkout@v3\n        with:\n          ref: ${{ github.event.pull_request.head.sha }}\n      - uses: actions/setup-node@v4.0.0\n      - uses: peaceiris/actions-gh-pages@v3\n      - uses: some-org/does-not-exist-xyz@v1\n      - run: echo \"Title: ${{ github.event.pull_request.title }}\"\n      - run: |\n          echo \"::set-output name=x::1\"\n          echo \"done\"\n"
    }
  ]
}

and gets back (recorded from the live server on 2026-09-26):

{
  "actions": [
    "actions/checkout@v3 -> v3.7.0, latest v7.0.1, node16",
    "actions/setup-node@v4.0.0 -> v4.0.0, latest v7.0.0, node20",
    "peaceiris/actions-gh-pages@v3 -> v3.9.3, latest v4.1.0, node16"
  ],
  "counts": {
    "error": 6,
    "warning": 4,
    "info": 2
  },
  "findings": [
    {
      "level": "error",
      "file": ".github/workflows/ci.yml",
      "line": 18,
      "code": "- run: echo \"Title: ${{ github.event.pull_request.title }}\"",
      "issue": "Script injection: ${{ github.event.pull_request.title }} is text an outside contributor controls, expanded into a shell script.",
      "fix": "Pass it through an environment variable: env: VALUE: ${{ github.event.pull_request.title }} and use \"$VALUE\" in the script."
    },
    {
      "level": "error",
      "file": ".github/workflows/ci.yml",
      "line": 14,
      "code": "ref: ${{ github.event.pull_request.head.sha }}",
      "issue": "pull_request_target workflow checks out the pull request's code: it runs untrusted code with the repository's secrets and a write token.",
      "fix": "Use pull_request for building contributed code, or keep the checkout of the base branch and never run the PR's code in this workflow."
    },
    {
      "level": "error",
      "where": ".github/workflows/ci.yml:12",
      "issue": "actions/checkout@v3 runs on Node 16, which GitHub has deprecated for actions.",
      "fix": "Update to v7.0.1 (runs on Node 24): actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1"
    },
    {
      "level": "error",
      "where": ".github/workflows/ci.yml:16",
      "issue": "peaceiris/actions-gh-pages@v3 runs on Node 16, which GitHub has deprecated for actions.",
      "fix": "Update to v4.1.0 (runs on Node 24): peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 # v4.1.0"
    },
    {
      "level": "error",
      "where": ".github/workflows/ci.yml:17",
      "issue": "some-org/does-not-exist-xyz@v1: github.com/some-org/does-not-exist-xyz does not exist or is private."
    },
    {
      "level": "error",
      "file": ".github/workflows/ci.yml",
      "line": 7,
      "issue": "runs-on ubuntu-20.04 (matrix.os): GitHub no longer provides this runner; jobs wait and fail.",
      "fix": "Use ubuntu-latest, or a current version from GitHub's runner-images list."
    },
    {
      "level": "warning",
      "file": ".github/workflows/ci.yml",
      "line": 20,
      "code": "echo \"::set-output name=x::1\"",
      "issue": "Deprecated workflow command ::set-output.",
      "fix": "write to $GITHUB_OUTPUT instead: echo \"name=value\" >> \"$GITHUB_OUTPUT\""
    },
... (32 more lines)

Tools

Tool

What it does

action_versions

For up to 20 actions (owner/repo, or owner/repo@ref): latest release with its commit SHA and runtime, the newest release of each major version, and for a ref, the commit it points to and its runtime, with the line to pin (action@sha # tag).

check_workflows

Reviews up to 30 workflow files (path and content): outdated actions and the SHA to pin, actions on deprecated Node runtimes, runner labels GitHub no longer provides, deprecated commands (set-output), script injection and pull_request_target risks. Findings with file, line and fix.

runner_labels

Status of GitHub-hosted runner labels (ubuntu-22.04, macos-14, windows-2019...) from GitHub's runner-images list: available, beta, deprecated, or retired (no longer provided). Without labels, every label GitHub lists now.

How it behaves

  • Read-only: no tool changes anything outside this process.

  • Network: HTTPS only, to the hosts listed in package.json under factory.allowHosts, with a deadline, a size cap and bounded retries. Nothing else is contacted, and nothing is logged except unexpected failures (to stderr, without your inputs).

  • Workflow files are read as text and never run. Tags come from git's own ref listing (github.com/<action>.git/info/refs), runtimes from each action's action.yml at the commit used, runner labels from actions/runner-images. Answers are cached for 30 minutes.

  • Local actions (./...) and docker:// images are not looked up.

  • Results are compact JSON with a matching output schema, errors first.

Benchmark

Measured 2026-09-26 with gpt-5.4-mini, 9 fixed tasks graded by fixed checks (bench/tasks.json, raw results in bench/results/).

Server

Correct

Input tokens

Output tokens

Tool calls

Median time

This server

8/9

12672

677

9

2.1 s

mcp-server-fetch reading GitHub (no workflow-checking server exists; this is what agents use today)

6/9

109430

898

21

4.2 s

Performance

Measured 2026-09-26 from Dubai, home connection against the live upstream, Node 24.19.0 (bench/perf.json, scripts/perf.mjs in the factory).

Call

First call

Repeat

Result size

check_workflows: a workflow with 12 problems

1028 ms

1.1 ms

3,383 chars

check_workflows: a clean, pinned workflow

648 ms

0.6 ms

117 chars

action_versions: 3 actions, with and without refs

1018 ms

0.9 ms

1,375 chars

runner_labels: 4 labels

251 ms

0.3 ms

293 chars

First call: a fresh server process, including the TLS connection and the upstream's own time. Repeat: the same call again, answered from the in-process cache, so it shows this server's own overhead.

Tool definitions the model reads on every turn (name, description, input schema): 1,450 characters, against 1,105 for mcp-server-fetch reading GitHub (no workflow-checking server exists; this is what agents use today). The full tool list, with the output schemas and annotations clients use to validate results, is 2,689 characters (1,104 for the alternative).

More MCP servers by Arhan Canli

  • Cron Check: Explains cron expressions, lists next run times in any time zone, converts between cron dialects.

  • Domain Health: Email and domain checks: SPF lookup limits, DKIM keys, DMARC, DNS records, registration expiry.

  • End of Life: Is this version still supported? EOL dates, latest patch and upgrade target for 470+ products.

  • Internet Standards: RFC sections, status, obsoleted-by chains, errata and IANA registries for coding agents.

  • License Check: Open source license answers: SPDX ids, copyleft, and whether a dependency's license fits yours.

  • Package Truth: Checks packages exist before install: version, deprecation, vulnerabilities, licence. 7 ecosystems.

  • Release Notes: What changed between two versions of a package: breaking changes, deprecations, security fixes.

  • Citation Check: Verifies citations: finds fabricated or mismatched references and retractions, returns clean BibTeX.

  • The whole collection, 7 more

License

MIT, Copyright (c) 2026 Arhan Canli.

Available Tools

3 tools
action_versionsVersions of an actionA
Read-onlyIdempotent

For up to 20 actions (owner/repo, or owner/repo@ref): latest release with its commit SHA and runtime, the newest release of each major version, and for a ref, the commit it points to and its runtime, with the line to pin (action@sha # tag).

ParametersJSON Schema
NameRequiredDescriptionDefault
actionsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultsYes

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, openWorldHint=true, and destructiveHint=false, so the safety profile is fully covered. The description adds return-content detail but does not disclose rate limits, pagination, or error behavior. With strong annotation coverage, a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence that front-loads the input constraint and enumerates outputs efficiently. No wasted words, though the structure is packed and could benefit from a slight split for readability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value explanation is unnecessary. Combined with safety annotations and the description's coverage of input format and output content, the definition is adequate for a read-only retrieval tool. Minor gaps (rate limits, response shape nuances) are acceptable given the annotations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate. It does by specifying the parameter format ('owner/repo, or owner/repo@ref') and the 20-item cap. This provides meaning the bare schema array lacks, though it could go further on delimiters or edge cases.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific resource ('actions') and enumerates the exact deliverables: latest release with commit SHA and runtime, newest release per major version, and ref resolution with pin line. The resource and return scope are unambiguous and clearly distinct from siblings check_workflows and runner_labels, which concern workflows and runner metadata respectively.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies its purpose (retrieving action version information) and is clearly distinct from the siblings by subject matter, but it does not explicitly state when to choose this over alternatives or provide exclusion conditions. The usage context is inferred rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_workflowsReview GitHub Actions workflowsA
Read-onlyIdempotent

Reviews up to 30 workflow files (path and content): outdated actions and the SHA to pin, actions on deprecated Node runtimes, runner labels GitHub no longer provides, deprecated commands (set-output), script injection and pull_request_target risks. Findings with file, line and fix.

ParametersJSON Schema
NameRequiredDescriptionDefault
filesYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
countsYes
findingsYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, openWorld, and non-destructive behavior, and the description is consistent with these. It adds useful behavioral detail by stating that the tool analyzes provided path/content pairs and returns findings with file, line, and fix.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single dense sentence that front-loads the resource and limit, then presents checks and output in a compact, scannable list. Every clause adds information and there is no repetition of schema or annotation details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter tool with a rich output schema and comprehensive annotations, the description covers the input contract, the analysis categories, and the output shape. It lacks only explicit routing guidance relative to siblings, which was already penalized under usage guidelines.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It does by explaining that 'files' are workflow files consisting of path and content, implicitly reinforcing the required structure and the 30-file limit. It could add more about content format, but the meaning is clear.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Reviews') with a clear resource ('up to 30 workflow files') and enumerates the exact checks performed. It is unambiguous about what the tool does and is easily distinguished from siblings by its review-oriented scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is for reviewing workflow files for security and maintenance issues, but it does not explicitly state when to prefer this over the sibling tools action_versions or runner_labels. Usage context is present only by inference from the listed checks.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

runner_labelsGitHub-hosted runner labelsA
Read-onlyIdempotent

Status of GitHub-hosted runner labels (ubuntu-22.04, macos-14, windows-2019...) from GitHub's runner-images list: available, beta, deprecated, or retired (no longer provided). Without labels, every label GitHub lists now.

ParametersJSON Schema
NameRequiredDescriptionDefault
labelsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultsYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false. The description adds valuable context: the possible statuses (including 'retired' meaning no longer provided) and the default of returning all labels if none are specified. This goes beyond the annotations without contradicting them, enriching the agent's understanding of behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core purpose, examples, and statuses, then the default behavior. Every sentence earns its place, with zero waste or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple with one optional parameter, and an output schema exists (so return format is covered). The description covers purpose, default behavior, and statuses. Annotations cover safety (read-only, non-destructive). It lacks explicit prerequisites or error conditions, but for a read-only status tool, the description is sufficiently complete for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate for the single optional 'labels' parameter. It does provide examples of label names and clarifies that omitting the parameter returns all labels, but it does not explicitly define the parameter's purpose (e.g., 'labels to check status for'). The description adds some meaning but not a direct parameter explanation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb+resource (status of GitHub-hosted runner labels) and gives concrete examples (ubuntu-22.04, macos-14, windows-2019) and statuses (available, beta, deprecated, retired). It clearly differentiates from sibling tools (action_versions, check_workflows) by focusing on runner labels, so an agent can identify the right tool without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by topic (runner labels vs. action versions or workflows) and clarifies the default behavior when the optional 'labels' parameter is omitted ('Without labels, every label GitHub lists now'). However, it does not explicitly state when to use this tool over alternatives or any exclusions, leaving the agent to infer from context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv0.1.0
    • First observedaction_versions
    • First observedcheck_workflows
    • First observedrunner_labels

TDQS

A4.1/5.0

Scored across 3 tools

Disambiguation5/5

Each tool targets a distinct concern: action_versions queries specific action metadata, check_workflows scans workflow files for issues, and runner_labels reports runner label availability. No two tools overlap in purpose or output, so an agent can select unambiguously.

Naming Consistency4/5

All names are lowercase snake_case and composed of two clear tokens, but the pattern varies: action_versions and runner_labels are noun phrases, while check_workflows is a verb_noun. This is a minor deviation from a fully consistent verb-first convention, but the names are still predictable and readable.

Tool Count5/5

Three tools is well-scoped for a focused actions-checking utility. Each tool covers a distinct and necessary capability (version lookup, workflow review, runner label status) without redundancy or bloat, and the count falls within the typical 3–15 range.

Completeness4/5

The set covers the core actions-checking needs: outdated action versions, deprecated runtimes, runner labels, deprecated commands, and security risks. A minor gap is that there is no tool to list workflows in a repository; the agent must supply workflow paths externally, but this is a workable limitation rather than a significant dead end.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    Not graded
    maintenance
    Connects AI assistants to GitHub Actions workflows to monitor CI/CD pipelines, view run logs, diagnose failures, and optionally trigger or manage workflows with granular permission controls.
    10
    1
    -
  • A
    license
    A
    quality
    C
    maintenance
    Local-only GitHub Actions and CI maintenance scanner for AI-built apps. Exposes scan, explanation, and fix-planning tools to MCP clients; modifies nothing and makes no outbound requests by default.
    3
    51 npm
    2
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Analyzes GitHub Actions workflows and performance, helping identify bottlenecks, failures, and optimization opportunities in CI/CD pipelines.
    24 npm
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Audits GitHub Actions workflow files for supply-chain risks like script injection, leaked tokens, unpinned actions, and broad permissions.
    -