@mushi-mushi/mcp-ci
The Mushi Mushi GitHub Action. It calls the same API the MCP server uses, from a short CI job: fail a PR while bug reports sit untriaged, have an agent open a fix PR for one report, run the pre-release gates on a commit, or refresh the crawler’s signed-in session.
Quick start
name: Mushi gate
on: [pull_request]
jobs:
coverage:
runs-on: ubuntu-latest
steps:
- uses: kensaurus/mushi-mushi/packages/mcp-ci@master
with:
api-key: ${{ secrets.MUSHI_API_KEY }}
project-id: ${{ secrets.MUSHI_PROJECT_ID }}
command: check-coverage
min-coverage: '0.9'check-coverage fails the step when fewer than min-coverage (default
0.8) of the project’s reports are classified. Classification runs on its own
when a report arrives; trigger-judge does not classify reports.
Gates on every PR
name: Mushi gates
on: [pull_request]
jobs:
gates:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
# Gates 1 + 2 read your ESLint report (eslint-plugin-mushi-mushi rules).
- run: npx eslint -f json -o mushi-eslint.json src/ || true
- uses: kensaurus/mushi-mushi/packages/mcp-ci@master
with:
api-key: ${{ secrets.MUSHI_API_KEY }}
project-id: ${{ secrets.MUSHI_PROJECT_ID }}
command: gates
eslint-report: mushi-eslint.json
commit-sha: ${{ github.event.pull_request.head.sha }}
pr-number: ${{ github.event.pull_request.number }}Commands
command: | What it does |
|---|---|
check-coverage | Fails when the classified share of reports is under min-coverage; sets the coverage output. |
trigger-judge | Starts the judge, which grades the AI classification of up to 50 classified reports not yet graded (projects with the judge turned on). It does not classify new reports. |
dispatch-fix | Queues an agent fix for report-id (optionally pinned with inventory-action-node-id). |
query | Runs a plain-English question against your reports and prints the answer. |
gates | Runs the gates for commit-sha (all = dead_handler, mock_leak, api_contract, status_claim, orphan_endpoint, unknown_call) and fails the step when one fails, errors or returns no result. |
discover-api | Walks your repo for Next.js route handlers and OpenAPI files (plus optional Supabase introspection) and sends the routes to Mushi Mushi for the api_contract gate. |
spec-drift | Gate 6: runs oasdiff breaking between base-spec and head-spec, records the findings and sets the findings output; fails on a breaking change unless fail-on-breaking: false. |
discovery-status | Reads what the SDK has observed; sets ready_to_propose, total_events and route_count outputs. |
propose | Asks the LLM proposer for an inventory.yaml draft and sets proposal_id. It does not open a PR. |
auth-bootstrap | Runs @mushi-mushi/inventory-auth-runner (npx --yes -p @mushi-mushi/inventory-auth-runner mushi-mushi-auth refresh) to refresh the crawler’s sign-in cookie. |
The action fails the step; it does not post a separate GitHub commit status.
dead_handler and mock_leak judge the findings in eslint-report (an
ESLint JSON report made with eslint-plugin-mushi-mushi).
A run that asks for them without a report fails, so a missing lint step can
never pass as “no findings”. crawl is not run by this command: start a crawl
with Reconcile on the Inventory page; api_contract reads its result. A
skipped gate prints its reason.
In your IDE
The same commands are exposed as MCP tools via @mushi-mushi/mcp.
Cursor, Claude Code, and Copilot can run them on your behalf when the MCP
server is configured. Inside the admin console you can also click
Run gates / Run crawler directly on each row of the User stories
page; see Admin → User stories · Inventory.
Inputs
action.yml is the source of truth; a test keeps it in step with the CLI.
| Input | Required | Default | Description |
|---|---|---|---|
api-key | ✓ | — | Project API key (mushi_…). Store it as a repo secret. |
project-id | ✓ | — | Project UUID. |
command | ✓ | — | One of the commands listed above. |
api-endpoint | hosted Mushi Mushi API | Override for self-hosted deployments. | |
report-id | for dispatch-fix | — | Report UUID. |
inventory-action-node-id | — | For dispatch-fix: the inventory action to pin the fix to. | |
question | for query | — | The question to ask. |
min-coverage | 0.8 | For check-coverage: the share of reports that must be classified. | |
fail-on-quota | true | Set false to warn instead of failing on QUOTA_EXCEEDED. | |
commit-sha | GITHUB_SHA | For gates and spec-drift: the commit to check. | |
pr-number | — | For gates and spec-drift: the PR the findings belong to. | |
gates | all | For gates: a comma-separated subset; crawl is refused. | |
eslint-report | for gates with dead_handler / mock_leak | — | ESLint JSON report (eslint -f json) made with eslint-plugin-mushi-mushi. |
repo-root | the workspace | For discover-api: where to look for routes. For gates: the root eslint-report paths are made relative to. | |
openapi-file | openapi.yaml in repo-root | For discover-api: an explicit OpenAPI file. | |
supabase-url, supabase-anon-key | — | For discover-api: optional Supabase introspection. | |
base-spec, head-spec | for spec-drift | — | Base and head OpenAPI specs (path or URL). |
fail-on-breaking | true | For spec-drift: fail on a breaking change. |
Outputs
| Output | Set by | Description |
|---|---|---|
result | most commands | JSON returned by the Mushi Mushi API. |
coverage | check-coverage | Observed classified ratio. |
findings | spec-drift | JSON array of the oasdiff findings. |
ready_to_propose | discovery-status | "true" once there is enough discovery data to propose. |
total_events | discovery-status | SDK discovery events recorded. |
route_count | discovery-status | Routes discovered. |
proposal_id | propose | Inventory proposal to review on /inventory. |
More workflow examples are in the package README .