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

@calltelemetry/pr-manager-mcp

v0.7.4

Published

Pull Request Management MCP Server for GitHub PRs, CI logs, review threads, and Linear policy validation

Readme

@calltelemetry/pr-manager-mcp

A Model Context Protocol (MCP) server for inspecting, accelerating, triaging, and managing GitHub Pull Requests, GitHub Actions CI workflows, review threads, test coverage, and Linear policy validation directly from AI coding agents.

Key Features

  • GitHub Actions Acceleration & Triage:
    • triage_ci_failures: Fast root-cause classification (deterministic_test, infrastructure, timeout, permission, queue_stall) with high-signal excerpts and suggested actions.
    • rerun_failed_jobs: Selectively retries only failing jobs without restarting full suites or passing matrix jobs.
    • cancel_superseded_runs: Automatically frees runner slots by canceling obsolete runs on older commits.
    • enable_auto_merge: Enables GitHub auto-merge (SQUASH / MERGE / REBASE) via GraphQL. On CLEAN no-queue PRs (UNPROCESSABLE: Pull request is in clean status), falls through to an exact-head mergePullRequest.
    • merge_pull_request: Direct protected squash/merge/rebase at expectedHeadSha for CLEAN PRs that cannot use auto-merge.
    • get_ci_snapshot: Single-call unified health snapshot (active runs, queued runs, stalled queues, blocker breakdown).
  • PR Status & Bounded Mergeability: Fetch complete PR metadata, status checks, and handles mergeable: null via automatic bounded polling.
  • Repository Visibility Guard: Read the live GitHub repository visibility (public, private, or internal) before making public/private-surface decisions.
  • CI Job Status & Step Logs: Query check runs, check suites, and download job execution logs with safe redirect handling and credential redaction.
  • PR State Monitor / Wait: Efficiently wait/poll for PR state transitions (checks_passed, checks_completed, clean_mergeable, bot_review_completed, merged, closed) without busy loops.
  • Top-Level PR Comments: Post issue comments to trigger bot reviews (e.g. @cursor-agent review) or attach CI evidence summaries.
  • Test Coverage Aggregation: Extract test coverage from CI check runs, bot comments (e.g. Codecov), or local coverage-summary.json files.
  • Draft Creation & Promotion Guard: Open draft PRs, run comprehensive prechecks (Linear policy, Customer Data / PII scrub, PR template completeness), and promote draft PRs to "Ready for Review" via GraphQL.
  • Canonical Compliance Allowlist: The Customer Data / PII scrub honors the same line-scoped ct-compliance:allow marker as the canonical ct-compliance/scripts/scan.sh. Put that literal anywhere on a line that legitimately must contain an otherwise-flagged shape — a required NetworkPolicy ipBlock.cidr, or a guard-rail test asserting a token's absence — and the line is counted as allowlisted (surfaced as summary.allowlistedCount) instead of reported as a finding. Marker content is never echoed, because CI logs are readable by anyone with repo access; audit the set with git grep ct-compliance:allow. The exemption is line-scoped only: it never excuses a different line, and never a filename — a customer-named file must still be renamed.
  • Pinned Public Upstream Classification: Live precheck can classify one Docker bridge occurrence in the complete newly added public DocsGPT images/docsgpt/context/overlay/docsgpt/app.py snapshot, only in calltelemetry/ct-infrastructure and only at SHA-256 d6c77b31bc3a7ee378c8692af4b4d962ace01d36785a4809a8f7a303f9c7db7a. The exact source digest, development redirect statement and occurrence position are bound after strict full-file diff reconstruction. Unknown or altered snapshots, paths or repositories; modified/renamed/partial/malformed diff sections; and manual caller claims receive ordinary scanning. This classification affects only that private-IP occurrence, reports summary.classifiedPublicUpstreamCount, and does not change marker counts or other detectors. The public test fixture uses deterministic gzip/base64 transport; native tests verify both compressed and decoded source digests. It supplies no runtime exemption.
  • Review Thread Lifecycle: List GraphQL review threads, reply to inline review comments, resolve/unresolve threads, and request bot (Bugbot) or human reviewers.
  • Optimistic Concurrency Guards: Write operations (reply_review_thread, resolve_review_thread, rerun_failed_jobs, enable_auto_merge) support expectedHeadSha validation to prevent acting on stale PR revisions.
  • Embedded Linear Policy Guard: 100% test-verified parity with Call Telemetry Linear policy rules (scripts/workflow-policy/linear-workflow-guard.mjs) without needing external CI execution.
  • Multi-tiered Auth Precedence: Configured token $\rightarrow$ GITHUB_TOKEN $\rightarrow$ local gh auth token via gh CLI.

Complete Registered MCP Tool Suite (25 Tools)

| Tool | Category | Description | Key Parameters | |---|---|---|---| | diagnose_github_access | Inspection | Read-only account and target-repository access metadata, one pinned credential, explicit unknown write authority | owner, repo, expectedAccount | | get_pr_details | Inspection | Query PR metadata, body, branch info, mergeable state, review decision | owner, repo, pullNumber, pollTimeoutMs | | get_repo_visibility | Inspection | Read-only query of repository visibility and private flag | owner, repo | | get_pr_checks | Inspection | Query check-runs, check-suites, and commit statuses for head SHA | owner, repo, pullNumber or ref | | get_job_logs | Inspection | Retrieve CI job execution logs with safe redirect handling and truncation | owner, repo, jobId, tailLines, maxBytes | | get_pr_coverage | Inspection | Extract line, branch, statement coverage from check runs, PR comments, or local reports | owner, repo, pullNumber, ref, localReportPath, thresholdPercent | | get_ci_snapshot | CI Acceleration | Unified high-signal CI health snapshot and blocker breakdown | owner, repo, pullNumber, includeTriage | | wait_for_pr_state | Monitoring | Efficiently wait/poll until a target PR state condition is satisfied | owner, repo, pullNumber, targetState, timeoutMs, intervalMs | | start_pr_wait_job | Monitoring | Start the same wait as a background job and return a jobId immediately (use for targets that may exceed ~45s; avoids gateway timeouts) | owner, repo, pullNumber, targetState, timeoutMs (max 6h), intervalMs | | get_pr_wait_job | Monitoring | Poll a background wait job: running → elapsed time, finished → full monitor result | jobId | | cancel_pr_wait_job | Monitoring | Cancel a running background wait job | jobId | | triage_ci_failures | CI Acceleration | Parse failed CI steps and logs to classify root causes with suggested actions | owner, repo, pullNumber or runId, maxJobs | | rerun_failed_jobs | CI Acceleration | Selectively rerun only failed jobs in a workflow run | owner, repo, runId, pullNumber, expectedHeadSha | | cancel_workflow_run | CI Acceleration | Cancel a specific running or queued workflow run | owner, repo, runId | | cancel_superseded_runs | CI Acceleration | Automatically cancel obsolete runs on older commits for a PR branch | owner, repo, branch, currentHeadSha | | trigger_workflow_dispatch | CI Acceleration | Trigger custom GitHub Actions workflow dispatches | owner, repo, workflowId, ref, inputs | | enable_auto_merge | CI Acceleration | Enable auto-merge; CLEAN no-queue PRs fall through to exact-head merge | owner, repo, pullNumber, mergeMethod, expectedHeadSha | | merge_pull_request | Landing | Exact-head GraphQL merge for CLEAN PRs (no merge queue, no admin merge) | owner, repo, pullNumber, expectedHeadSha, mergeMethod | | disable_auto_merge | CI Acceleration | Disable auto-merge on a pull request | owner, repo, pullNumber | | list_review_threads | Reviews | Query GraphQL review comment threads with resolution status | owner, repo, pullNumber, includeResolved | | reply_review_thread | Reviews | Reply to an existing review thread with expectedHeadSha guard | owner, repo, pullNumber, threadId, body, expectedHeadSha | | resolve_review_thread | Reviews | Resolve or unresolve a review thread with expectedHeadSha guard | threadId, resolve, expectedHeadSha | | request_reviewers | Reviews | Request reviews from users, teams, or bot accounts | owner, repo, pullNumber, reviewers, teamReviewers, botReviewers | | add_pr_comment | Comments | Post top-level comments on a PR to trigger bot reviews or post evidence | owner, repo, pullNumber, body | | create_draft_pr | Lifecycle | Open a new pull request on GitHub (defaults to draft mode) | owner, repo, title, head, base, body, draft | | precheck_pr | Lifecycle | Run pre-promotion validation (Linear policy, Customer data/PII scrub, template evidence) | owner, repo, pullNumber (or raw branch/title/body) | | promote_pr_to_ready | Lifecycle | Promote draft PR to Ready for Review via GraphQL with gated prechecks | owner, repo, pullNumber, force, overrideReason | | check_linear_policy | Policy | Validate PR branch name, title, and body against Linear policy | sourceBranch, targetBranch, prTitle, prBody |

Scoped GitHub workspace tools

The Bifrost-federated pr-manager can expose three explicit repository tools:

| Tool | Operation | Guard | |---|---|---| | get_repo_file | Read a UTF-8 file and blob SHA | 128 KiB maximum; selected server-side credential | | create_work_branch | Create a new codex/ branch | Exact current base commit SHA; no ref update | | put_work_file | Commit one UTF-8 file on a codex/ branch | Exact parent and blob SHA; non-forced ref advance rejects concurrent changes; 128 KiB maximum |

These tools are absent by default. Enable registration only with PR_MANAGER_GITHUB_WORKSPACE_TOOLS=enabled after narrowing wildcard pr_manager grants in the Bifrost roster and validating the intended per-key ACLs. They do not merge, change protection, install an App, or choose a different account after a permission failure. If a ref update acknowledgement is lost, the tool reads the branch once: it returns success only when the proposed commit is observed, otherwise UNKNOWN_GITHUB_EFFECT requires inspection before retry. GitHub still enforces the installation's repository and Contents permissions. A 403 Resource not accessible by integration requires an authorized installation or a separate authorized PR route. Register only the intended tool names for each Bifrost virtual key via the existing roster writer; source registration alone does not grant access.

Read-only access diagnostic

Run pr-manager-mcp auth-doctor <owner> <repo> [expected-account], or use the equivalent diagnose_github_access MCP tool. Both use the existing token resolver and pin its selection for the operation. Use the same process-scoped credential environment as the intended Git operation; no account or global Git configuration is changed. The source category describes the resolver input, not an inferred upstream broker identity.

Only two bounded GET probes run: authenticated user metadata and the exact target repository. Output preserves 401, 403, hidden-or-missing 404, malformed response, rate-limit and transport outcomes without returning response bodies or secrets. An installation token may not identify a user; account/App identity then remains unknown. Repository role is not proof of the token's effective write scope (fine-grained tokens can be more restrictive). No write is attempted to test it. CLI exit 0 means target metadata is readable and any requested account matches; it does not authorize a push, merge, or privilege change.

See GitHub authentication permissions.

Setup & Configuration

Transports

The containerized server (dist/sse.js, the default CMD in the Docker image) exposes:

| Endpoint | Transport | Notes | |---|---|---| | POST /mcp | MCP Streamable HTTP (spec 2025-03-26) | Session-based; responses stream over SSE with 15s keep-alive frames, so a blocking tool call never lets the connection go idle long enough to trip an intermediary's inactivity timeout. Open with initialize, then send mcp-session-id on subsequent calls. | | GET /sse + POST /messages?sessionId=… | Legacy HTTP+SSE | Emits : keepalive comment frames every 15s. | | GET /healthz | Health probe | Returns the active transport set. | | GET /metrics | Prometheus text (0.0.4) | Counters only — no tokens, request paths, or repository contents. Unauthenticated like /healthz; handled before the MCP session machinery so a scrape never reserves a session slot. |

Tunable via environment or server options: SSE_KEEPALIVE_MS (default 15000), MAX_STREAMABLE_SESSIONS (default 100), STREAMABLE_SESSION_TTL_MS (default 30 min — idle Streamable HTTP sessions are reaped so abandoned clients cannot exhaust the cap), and MAX_RUNNING_WAIT_JOBS (default 50 — bound on concurrently polling background jobs).

Metrics

GET /metrics exposes counters in Prometheus text format, emitted by a dependency-free registry (src/utils/metrics.ts): the surface is small enough that prom-client would add weight to a deliberately lean image. Revisit if histograms or exemplars are needed.

| Metric | Labels | Meaning | |---|---|---| | pr_manager_github_requests_total | method | GitHub API requests attempted. The denominator for the failure rate. | | pr_manager_github_auth_failures_total | status | 401 = token expired, revoked or invalid. 403 = token lacks the required scope. Kept separate because the remediation differs. | | pr_manager_token_resolution_failures_total | source | Failures to resolve a token at all, by resolution source. |

Counted after the 401 fallback, deliberately. A 401 that the fallback recovers from is a healthy request; counting the first response would make a rate alert fire on a working system. Only a surviving 401/403 is counted. test/unit/auth-metrics.test.ts pins both directions.

Suggested alert: rate(pr_manager_github_auth_failures_total[10m]) > 0 for 10m. A sustained non-zero rate means the credential is stale, revoked, or under-scoped — the silent failure mode where requests keep succeeding until a short-lived token expires and only then start failing.

Async wait-job resource bounds

Background wait jobs are reachable by any client of the server, so the store defends itself:

  • Concurrent running jobs are capped (MAX_RUNNING_WAIT_JOBS); over the cap, start_pr_wait_job is refused.
  • Job ids are random UUIDs — they are the only handle on a job, so a predictable id would let one client read or cancel another's.
  • cancel_pr_wait_job aborts the underlying poll loop (AbortSignal threaded into the monitor) and is sticky: a cancelled job never flips to satisfied/timeout when the in-flight poll settles.
  • Each wait binds its first observed head, or the supplied expectedHeadSha. A head change ends the stage as stale_head; unreadable checks produce unconfirmed rather than reusing prior success. A satisfied condition is an observation, not review or merge approval.
  • To reuse one owned monitor, supply a private random UUID monitorScopeId and an exact expectedHeadSha to start_pr_wait_job. The same scope/repository/PR/target/head reuses its running job. A different head supersedes only that scope's same stage. Treat the UUID as a capability: keep it within the caller/mission, never use a public issue name, and do not publish it. The server retains only its hash. Omitted or different scopes keep clients independent.

Sync vs async waits

wait_for_pr_state holds its HTTP request open for up to 5 minutes. Every hop in front of the server bounds idle connection time (the ingress defaults to timeout server 50s), so on a gatewayed deployment a long synchronous wait can be cut with a 504 before the tool finishes — even though the transport keeps the stream alive, an intermediary may still cap total connection time.

For targets that may take longer than ~45 seconds, prefer the async form:

  1. start_pr_wait_job → returns jobId in milliseconds.
  2. Poll get_pr_wait_job with the jobId (~5s interval suggested).
  3. Optionally cancel_pr_wait_job.

.mcp.json Registration

Add the server to your project's .mcp.json:

{
  "mcpServers": {
    "pr-manager": {
      "type": "stdio",
      "command": "node",
      "args": [
        "pr-manager-mcp/dist/index.js"
      ],
      "env": {
        "GITHUB_TOKEN": "${GITHUB_TOKEN}",
        "CT_LINEAR_TEAM_PREFIXES": "${CT_LINEAR_TEAM_PREFIXES:-}"
      }
    }
  }
}

Building & Running Tests

cd pr-manager-mcp
npm install
npm run build
npm test

Landing result truth and fail-closed CI reads

enable_auto_merge and pr_land make at most one enable attempt, then read current identity-bound state. The outcome is queued, merged, armed, refused, or unconfirmed. A null mutation autoMergeRequest is not proof of refusal: protected queue admission and immediate merge can both return it. Queue position/state are preserved when available. Unknown queue/auto-merge/thread metadata are explicit, never an absent queue or a ready-to-merge claim; inspect current state instead of automatically repeating a mutation.

CLEAN direct merge is permitted only after fresh unchanged PR head/base identity and complete successful effective branch-rule pagination prove no merge queue applies. A CLEAN error alone is not that proof. Missing, partial, contradictory, or unreadable state refuses the fallback.

Migration note: CI collection is fail-closed. Permission failures (including 403), 404, transient 5xx, malformed/incomplete pagination and exhausted collection budgets are errors, not empty successful check lists. Existing required-context/App-bound checks, exact-head, review-thread, Linear and customer-data gates still apply. Protected source merge, release, deployment, and live acceptance remain separate receipts.