Why run it in CI
A localmcpscore check is a snapshot; CI makes quality a standard you can’t
regress past:
- Catch regressions before merge. A refactor that drops a tool description or breaks a schema shows up as a failing check on the PR — not in production, inside someone else’s agent.
- A visible quality bar. The score and its trend live on the PR, so reviewers and contributors see the impact of a change without running anything.
- Readiness tracking for the next spec. The action reports the separate readiness score for the upcoming MCP revision, so you know where you stand well before it lands.
- Deterministic and fast. No API keys, no LLM calls — the same server state always produces the same result, in seconds.
Quick start
Gate a pull request on quality. Thepull-requests: write permission lets the
action post its comment.
pull-requests: write is the permission GitHub’s token uses to comment on a pull
request — the same scope every PR-comment action uses. (The comment goes through
the issue-comments API, but the token’s pull-requests scope is what authorizes
it for a PR.)
On pull requests from a fork, GitHub gives the workflow token read-only
access, so the comment can’t be posted. The audit and the score gate still run
normally — only the comment is skipped. To comment on fork PRs, run the audit in
a
pull_request_target workflow, and review the
security implications
of doing so first.Audit a local server from the repo
For a server that lives in the repository, check out the code and pointtarget
at the entry file:
Also require readiness for the upcoming spec
The readiness gate only applies when the server was actually assessed for
readiness. A stdio server audited without probes reports no readiness score, and
min-readiness is skipped rather than failing the build.Use the outputs in later steps
Every number is exposed as a step output:What you get on the PR
The action posts one comment and updates it in place on every re-run — no comment spam. It contains the overall score, a pass/fail breakdown by severity, the negotiated spec version and era, the separate readiness score, and a collapsible list of every failed check byrule_id (so a fix is one lookup in
the rules reference away). The same report is written to the run’s job
summary.
Inputs
| Input | Default | Description |
|---|---|---|
target | — (required) | MCP server URL, or a local .py / .js path |
version | latest | mcpscore version to run (e.g. 0.8.0) |
min-score | none | Fail if the main score percentage (0–100) is below this |
min-readiness | none | Fail if the readiness percentage (0–100) is below this |
comment | true | Post / update the report comment on the pull request |
args | — | Extra arguments passed to the mcpscore CLI |
report-path | mcpscore-report.json | Where the JSON report is written |
github-token | github.token | Token for the PR comment (needs pull-requests: write) |
Outputs
| Output | Description |
|---|---|
score / max-score / percentage | Main score |
readiness-score / readiness-max / readiness-percentage | Next-spec readiness score |
era | legacy, modern, or dual-era |
negotiated-version | Spec version the server negotiated |
Pinning the version
@v1 follows the latest v1 release, so you get fixes automatically. For fully
reproducible runs, pin the action to a commit SHA and pin version to a specific
mcpscore release:
See also
Scoring Methodology
How the score works, and why the readiness axis is separate
Rules Reference
Every rule the action can flag, by
rule_idAction source
mcp-box/mcpscore-action on GitHub
mcpscore CLI
Run the same audit locally