npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

whyfail-mcp

v0.1.0

Published

MCP server for WhyDidThisFail? -- lets AI agents call live build/CI failure diagnosis directly.

Downloads

151

Readme

whyfail-mcp

An MCP (Model Context Protocol) server for WhyDidThisFail? -- lets an AI agent (Claude Code, Claude Desktop, or any MCP-compatible client) call real build/CI failure diagnosis mid-task, instead of a human needing to paste a log in manually.

A separate package from the whyfail CLI on purpose, mirroring the same reasoning PackageSafe applied for safecheck-mcp: the CLI has a minimal dependency footprint for fast npx installs, and the MCP SDK + schema library are real dependencies that only people who want MCP integration should have to pull in. It implements no diagnosis logic itself -- both tools are thin wrappers around the live WhyDidThisFail API, reusing the published whyfail package's own API-calling code (whyfail/lib/diagnose.js) rather than duplicating it.

Install

npm install -g whyfail-mcp
# or run without installing, via npx (see config examples below)

Zero configuration needed: it talks to the live production diagnosis API (https://whydidthisfail-production.up.railway.app) by default, same as the published CLI.

Configure

Claude Code

claude mcp add whyfail -- npx -y whyfail-mcp

(Local/project scope by default. Add --scope user instead to make it available across all your projects.)

Claude Desktop

Add to your claude_desktop_config.json:

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

Any other MCP-compatible client

It's a standard stdio MCP server -- run npx -y whyfail-mcp (or whyfail-mcp if installed globally) as the command; no special transport config needed.

Tools

diagnose_log

Diagnoses a build/test/CI failure from raw log text you already have. Auto-detects the format (Python tracebacks, npm/pnpm errors, Docker build failures, GitHub Actions job logs, TypeScript compiler errors, Terraform plan/apply failures) and returns cause, explanation, fix, exact commands, and whether the answer came from the pattern database (source: "pattern") or a live LLM call (source: "llm").

| Input | Required | Description | | --- | --- | --- | | log | yes | The raw failure output. | | format_hint | no | Skip auto-detection if the format is already known. |

diagnose_ci_failure

Diagnoses a failed GitHub Actions run directly from a run URL or repo+run-id: fetches the failed job's logs from GitHub, then runs them through the same diagnosis as diagnose_log.

| Input | Required | Description | | --- | --- | --- | | run_url | one of run_url or owner+repo+run_id | e.g. https://github.com/owner/repo/actions/runs/123456789 | | owner, repo, run_id | | Alternative to run_url. | | job_name | no | Restrict to one job, if the run has more than one failed job. | | github_token | needed in practice | See below. |

GitHub token: confirmed by real testing against a real public repo -- GitHub's job-logs endpoint (/actions/jobs/{id}/logs) returns 403 without a token, even for public repos. This is not the same as the "works unauthenticated at low rate limits" behavior the list-runs and list-jobs endpoints have; a token is effectively required, not just a nice-to-have. Pass github_token, or set GITHUB_TOKEN/GH_TOKEN in the server's environment (see the Claude Code --env example above).

Completed runs only -- confirmed limitation, not a bug: this only works once a run has fully finished (status: "completed"). GitHub's API does not make job logs available for a run that's still in progress -- confirmed directly (see the whydidthisfail-action project, which hit this exact wall trying to self-diagnose a still-running job). The tool checks the run's status up front and returns a clear message rather than a confusing GitHub error if you call it too early -- there's no retry or workaround, just wait for the run to finish.

Worked example

A user typing, to an agent mid-task:

"the build just failed with npm ERR! code ERESOLVE ..., why?"

The agent should call diagnose_log (not need the tool name spelled out -- the description is written to match this exact kind of request) with the pasted error text as log, and get back something like:

{
  "detected_format": "npm",
  "source": "pattern",
  "pattern_id": "npm-eresolve",
  "cause": "npm can't find a set of dependency versions that satisfies every package's peer dependency requirements.",
  "explanation": "One installed (or requested) package declares a peerDependency version range that conflicts with what another package, or the root project, requires. Since npm 7, this is a hard error instead of a warning.",
  "fix": "Update the conflicting package(s) to versions whose peer dependency ranges are compatible...",
  "commands": ["npm install --legacy-peer-deps", "npm ls <package> (see which packages require conflicting versions)"]
}

For a request like "why did my GitHub Actions run fail? https://github.com/owner/repo/actions/runs/123456789", the agent should call diagnose_ci_failure with that URL as run_url instead.

Testing

test/verify.js is a real end-to-end check: it spawns bin/whyfail-mcp.js as an actual child process and drives it with the MCP SDK's own Client + StdioClientTransport over real stdio -- the same mechanism a real MCP host uses, not an in-process function call. Every diagnosis call hits the live production API for real, no mocking:

npm install
node test/verify.js

What it proves:

  • Both tools are discoverable via a real listTools() call, and their descriptions cover the natural-language requests they should match ("why did this fail", "diagnose this CI run", etc.) without needing the tool name spelled out.
  • diagnose_log against a real pattern-matched log (npm ERESOLVE) returns the correct source: "pattern" result from the live API.
  • diagnose_log against a real, deliberately unusual log (a numpy broadcast shape mismatch, not in the pattern database) correctly escalates to the live LLM path and returns a real, specific diagnosis -- this was genuinely exercised, not assumed, since production has both a working API key and available credit at the time of testing.
  • diagnose_ci_failure against a real, completed, public GitHub Actions run from this project's own repo: confirms URL parsing, the completed-status check, and job-filtering all work against the live GitHub API, and that a 403 at the final log-download step (no token available in the test environment) produces the actionable error message above rather than a bare status code.

What this doesn't prove: the full diagnose_ci_failure happy path (an actual successful log fetch) needs a real github_token, which wasn't available in the environment this was built in -- the error path up to that point is fully verified, the final authenticated fetch itself is not.