nixkeeper-mcp
OfficialThis read-only MCP server answers questions about nixpkgs package health, maintenance, and review state using nixkeeper's public dashboard and digests.
Inspect one package: versions, Hydra builds, update-bot attempts, PRs/issues, CVEs, maintainers/teams, staging/staging-next status.
Find packages by name and see whether they are failed, outdated, up to date, or vulnerable.
List packages needing attention by maintainer, team, list, kind, platform, or dashboard-style query; include merge-bot candidates.
Get an all-nixpkgs overview: counts, trends, newest/longest failures, blocking dependencies, failure reasons, recent fixes.
Search Hydra build failures by package, system, status, reason, age, or blocking dependency.
Search open PRs by package, author, bucket, base branch, merge-bot readiness, or update-bot blockage.
Search open issues about packages, including build-failure and update-request verdicts.
Inspect update-bot attempts by package, outcome, reason, or time.
Look up CVEs/advisories for a package, packages for a CVE, or worst current vulnerabilities.
Check data freshness and cache status; works over stdio, needs no account/token, and can answer from cache/offline.
Provides tools for querying open nixpkgs pull requests and issues, including by package, author, bucket, base branch, merge-bot readiness, and whether an issue appears already resolved. It also uses GitHub-hosted digest data for related build, update-bot, and vulnerability information.
Provides tools for querying nixpkgs package status and NixOS ecosystem data: outdated packages, Hydra build failures, update-bot attempts, CVEs and advisories from the NixOS security tracker, maintainers and teams, and staging-next impact.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@nixkeeper-mcpwhat's wrong with wesnoth?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
nixkeeper-mcp
An MCP server that lets an AI assistant answer questions about nixpkgs packages from nixkeeper's data: is a package outdated, does it build on Hydra, what did the update bot make of it, which PRs and issues touch it, which CVEs affect it, and what needs attention for a maintainer or a team. It runs on your computer over stdio, downloads only public files, and needs no account or token.
Using it
Install it once, then tell your assistant to start it. With Nix:
nix profile install github:nixkeeper/nixkeeper-mcpAnd with Claude Code:
claude mcp add --scope user nixkeeper -- nixkeeper-mcpThen ask: "what's wrong with wesnoth?", "which of iedame's packages need attention?", "what broke on Darwin in the last day?", "which open PRs could the merge bot merge for the Gaming team's packages?", "which of my packages break when staging-next is merged?"
Any MCP client that starts a server on stdio works the same way, with the
command nixkeeper-mcp. nix profile upgrade nixkeeper-mcp brings it up
to date. Without Nix: python3 -m nixkeeper_mcp in a checkout (Python 3.11
or later, standard library only).
With Home Manager
The flake has a Home Manager module. It adds the server to Home Manager's
shared MCP servers (programs.mcp.servers), which the assistants Home
Manager configures read when their enableMcpIntegration is on: Claude
Code, GitHub Copilot CLI and others. The server is the one your flake lock
pins, so there's no claude mcp add, and nothing to download or build when
an assistant starts it.
# flake.nix
inputs.nixkeeper-mcp = {
url = "github:nixkeeper/nixkeeper-mcp";
inputs.nixpkgs.follows = "nixpkgs";
};
# Home Manager
imports = [ inputs.nixkeeper-mcp.homeModules.default ];
programs.nixkeeper-mcp.enable = true;
programs.claude-code.enableMcpIntegration = true;The module's options are the server's: ttl, offline, cacheDir, and
dashboard, digestOwner and page for another instance's data (see
Options below); name is the server's name for the assistants
(nixkeeper), and package the build to run. The module is also
homeManagerModules.default, for setups that look for that name.
To try it first
claude mcp add --scope user nixkeeper -- nix run github:nixkeeper/nixkeeper-mcpThis runs it without installing anything, but Nix fetches the flake on every start, and asks GitHub again once its copy is an hour old. The first start downloads and builds it, which can take longer than an assistant waits for a server to start (30 seconds in Claude Code): if it gives up, start it again once the build is done, or install it as above.
Related MCP server: SecureLLM MCP Server
The tools
Tool | Answers | From |
| Everything about one package: nixpkgs' version against upstream's, master's, Hydra's builds on each platform (why a failure failed, when it last built, platforms it's listed for but never built on), the update bot's latest attempt and when it tries next, its update PR and other PRs and issues, CVEs with nixkeeper's verdict against nixpkgs' version, maintainers and teams; an update merged into staging or staging-next on its way to master, and whether staging-next breaks the package; and what the hourly digests have that's newer than the dashboard's last sync | the dashboard's row, the builds and update-bot digests |
| Packages by name, with their status | the dashboard |
| What needs attention (failing, outdated, vulnerable, a fix to backport), all of nixpkgs or one maintainer's, team's or list's, by kind and platform, worst first; or what breaks on staging-next (a forecast, its own kind); for a maintainer or team, also the PRs they can merge now with the merge bot ( | the dashboard's views, digest-prs |
| All of nixpkgs: counts and trends' latest, the page's "nixpkgs in numbers", the newest and longest-standing failures, the dependencies blocking the most builds, why builds and the bot fail, what was fixed this week | the dashboard |
| Hydra builds of master that aren't ok: by package or set, system, reason, the dependency that blocked them, since when; newest or longest failing first | digest-builds |
| Open nixpkgs PRs: touching a package, by author, bucket, base branch; ready for the merge bot, those a maintainer can merge with it ( | digest-prs |
| Open nixpkgs issues about a package; build failures that build now, update requests already done | digest-prs |
| The update bot's latest attempts: one package's with its place in the queue, or by outcome, reason, since when | digest-update-bot |
| One package's CVEs and advisories, one CVE's packages, or the worst affecting something now | digest-vulnerabilities |
| When each source was last made and read, and what's cached | every |
needs_attention's query takes the words of the dashboard page's search
box: is: one card (outdated, failed, builds, updates,
vulnerable, backport, broken, staging-next-breaks), is:unbuilt,
-is:broken, has:pr, -has:pr, -has:maintainer, on:linux or
on:darwin, in: a package set, team:, by: or @handle, and words of
a name; without is:, every package of the maintainer's or team's, as the
page lists them. A word it can't apply (age:, sort:, status:...) is
refused rather than left out, and each answer links the page with the
query (query.page), which takes them all.
Every answer says when its data was read (readFrom, times in UTC), and
says so when a source couldn't be reached and the answer comes from what
was cached. nixkeeper's checks (an issue that looks done, a PR ready for the
merge bot, an attempt that looks superseded, a package staging-next will
break) are hints for a person to check, not decisions: the server only
reads, and never comments on, closes or merges anything. Its tools say so
to the client (readOnlyHint), which may then run them without asking.
Where the data comes from
nixkeeper.com's data (
/data/, the community dashboard: every nixpkgs package, synced every 3 hours): each package's row, with everything nixkeeper joined from the digests and its verdicts (outdated, failing, vulnerable, to backport), so a package's state reads as the page shows it. Its format: nixkeeper's docs/data.md.The digests (the
databranch of each repository, each README saying its format), fresher and searchable across nixpkgs: digest-builds (Hydra, hourly), digest-prs (open PRs and issues, hourly), digest-update-bot (nixpkgs-update, every 3 hours), digest-vulnerabilities (the NixOS security tracker and OSV, hourly), and digest-versions' metadata (Repology's versions are in the dashboard's rows).
A file is downloaded the first time a tool needs it, so a question about one
package fetches that package's shard of the dashboard (about 90 KB) and the
two digests it's compared with, not all of nixpkgs. Files are kept in
$XDG_CACHE_HOME/nixkeeper-mcp (~/.cache/nixkeeper-mcp by default; about
35 MB with every source) and used for 15 minutes; after that, the server
asks whether a file changed (its ETag: an unchanged file isn't downloaded
again). If a source can't be reached, the cached file is used and the
answer says so. Parsed files stay in memory while the server runs: up to
about 400 MB with every source loaded at once (Hydra's 217,000 builds are
kept as text and searched, not parsed: parsed, they alone would take that
much). Every request names this repository in its
User-Agent.
Options
nixkeeper-mcp [--cache-dir DIR] [--ttl MINUTES] [--offline] [--call TOOL [JSON]]--cache-dir(orNIXKEEPER_MCP_CACHE): where files are kept.--ttl: minutes a file is used before asking whether it changed (default 15).--offline: never download; answer from the cache.--call TOOL '{"name": "wesnoth"}': run one tool and print its answer, to try them without an assistant.
NIXKEEPER_MCP_DASHBOARD (default https://nixkeeper.com/data/) and
NIXKEEPER_MCP_DIGEST_OWNER (default nixkeeper) point it at another
instance's data, a fork's; the answers link to the page beside the
dashboard's data (https://nixkeeper.com/), or NIXKEEPER_MCP_PAGE.
With Claude Code, options go after the command:
claude mcp add nixkeeper -- nixkeeper-mcp --ttl 60.
The protocol
The server speaks MCP over stdio, both its current revision (2026-07-28:
no handshake, each request carrying its version in _meta, and
server/discover) and the earlier ones (2025-11-25 back to 2024-11-05,
with initialize), whichever the client opens with. Tools only: no
resources or prompts. It's written with the standard library alone
(nixkeeper_mcp/protocol.py), like the digests, so it runs with any
Python 3.11 or later and has nothing to install.
Development
nix flake check runs the tests (which never ask the real sources), lint
and the formatting check; nix fmt formats; nix develop has the tools.
Releases: bump the version in pyproject.toml and
nixkeeper_mcp/__init__.py, move CHANGELOG.md's Unreleased entries under
the new version, and once that's merged, push a tag vX.Y.Z on main's
commit: .github/workflows/release.yml checks it and publishes the GitHub
Release with that section as its notes.
AI & automation disclosure
This server's code and documentation are written with the assistance of an AI (Claude, by Anthropic), with a person in the loop: nixkeeper's maintainer decides what to build, and reviews and tests every change before it's merged. It reads public data only, and never comments on, closes or merges anything in nixpkgs.
License
MIT
Available Tools
10 toolsbuild_failuresHydra build failuresARead-only
Search Hydra's builds of nixpkgs master (the builds digest, hourly) that aren't ok: failed (the package's own failure, with why from its log and an excerpt), dependency (blockedBy: which dependency failed), unfinished, queued. Newest first, or longest failing first. With the last success of each.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | newest (default: finished most recently) or longestFailing (never succeeded, then oldest last success). | |
| limit | No | At most this many results (default 50). | |
| since | No | Only since then: "24h", "7d", "2w", or a day or time (ISO 8601). | |
| reason | No | Why a failed build failed: compile, tests, link, header, cmake4, cmake, boost, pythonImport, pythonDeps, pythonBuild, pythonMetadata, haskellDeps, npm, lisp, home, download, hash, patch, substitute, missingFile, symlinks, patchelf, autotools, disk, other, noLog. | |
| search | No | Part of an attribute. | |
| status | No | failed (default), dependency, unfinished, queued, or notOk for all of them. | |
| system | No | A Hydra system. | |
| package | No | An attribute, or a set's prefix (python313Packages): its builds and its members'. | |
| blocked_by | No | Dependency failures blocked by this attribute (status dependency). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so safety is covered. The description adds real value beyond that: data source and freshness ("the builds digest, hourly"), the meaning of each status (dependency -> blockedBy which dependency failed), sort order, and return content ("with the last success of each"). Only auth/rate-limit context is absent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded: the verb/resource/scoping sentence comes first, followed by two short fragments on ordering and return content. It is telegraphic rather than wasteful, though the run-on enumeration of statuses is a little heavy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 9 params and no output schema, the description should carry return-value burden, and it does partially explain result content (why from the log, an excerpt, last success). It leaves other params (system, package, blocked_by, since, reason, limit) to the schema, which fully documents them.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description nevertheless adds semantics the schema lacks, explaining what the status categories mean (e.g. dependency failures expose blockedBy) and what each sort yields ("newest" vs "longest failing first"), which genuinely helps parameter selection.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Search Hydra's builds of nixpkgs master that aren't ok") and enumerates the four status categories it returns. An agent can immediately tell this is a read-only failure-listing tool, distinct from siblings like find_packages or needs_attention.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the scope description (finding non-ok builds), but there is no explicit when-to-use, when-not, or named alternative. Siblings such as needs_attention and update_attempts could overlap, and nothing here routes the agent between them.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
data_statusData freshnessBRead-only
When each digest and the dashboard were last made and read (their meta.json files), and what this server has cached.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds useful context beyond that: the values come from meta.json files, and it also reports what the server has cached. It does not mention cost, latency, or whether cached data can be stale relative to the files.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler. The parenthetical '(their meta.json files)' is slightly awkward but it is the one piece of implementation detail that clarifies where the timestamps originate, so it earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, read-only status tool with no output schema, the description covers the three things returned: per-digest timestamps, dashboard timestamps, and cache state. Return formatting details are absent, but with no output schema and no parameters there is little else an agent needs to call it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters (schema coverage 100%), so the baseline is 4 per the rubric. There is no argument syntax to explain, and the description correctly implies a no-argument call.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the concrete outputs (last-made/last-read timestamps for each digest and the dashboard) and the backing source (meta.json files), plus the server's cache state. That is specific enough to separate it from every sibling (find_packages, build_failures, overview, etc.), none of which are status/freshness tools. It lacks a crisp verb like 'report' or 'show', but the resource and scope are clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to reach for this tool versus siblings such as overview or needs_attention, and no exclusions or prerequisites. The agent must infer from the description alone that this is a freshness/cache inspection call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_packagesFind packagesARead-only
Find nixpkgs packages by name (exact, then starting with, then containing the query), each with its status: failed, outdated, up to date, vulnerable.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | At most this many results (default 20). | |
| query | Yes | Part of a name. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so the description only needs to add context. It adds the result ordering rule and the fact that each result carries a status label, but says nothing about truncation behavior beyond the schema's limit, case sensitivity, or how statuses are computed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One dense sentence with no filler; the match strategy and return payload are front-loaded where an agent will read them.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully enumerates what comes back (name plus status categories). For a two-parameter read-only search this is largely sufficient; only edge-case behavior like empty results or case sensitivity is unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3; the description earns an extra point by explaining the matching precedence for 'query' (exact → starts-with → contains), which the schema's 'Part of a name' does not convey. The 'limit' parameter is left to the schema, which documents it fully.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (find), a specific resource (nixpkgs packages), and even the match strategy and returned fields. It does not explicitly distinguish itself from the sibling 'package' tool (likely a single-package detail lookup), so it falls just short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The match ordering (exact, then prefix, then contains) implies how to phrase a query, which is implicit usage guidance. However, there is no explicit statement of when to use this versus 'package' or 'needs_attention', and no exclusions or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
issuesOpen nixpkgs issuesARead-only
Search nixpkgs' open issues by title (the PR digest, hourly). Build-failure issues have hydra: what Hydra builds now say (builds: a candidate to close; failing; waiting; removed; ...); update requests have update: whether nixpkgs has the version asked (done, partly, open) and the update bot's plans.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | build (build failures) or update (update requests). | |
| limit | No | At most this many results (default 30). | |
| search | No | Part of the title. | |
| package | No | Issues about it: the package a build failure or update request names, or its name whole in the title (not pkg-config for pkg). | |
| verdict | No | The digest's verdict: builds, failing, waiting, variant, noJob, platformNotBuilt, removed, renamed, unfree, markedBroken, notForHydra (build); done, partly, open, notFound, notVersion (update). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the read-only/open-world safety profile, and the description adds genuinely new behavioral context: this is a derived hourly PR-digest view, and each issue kind carries different derived fields (hydra verdicts vs. update status). That provenance is useful and non-obvious, though the phrasing 'the PR digest, hourly' is terse.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first clause, which is good, but the remainder is a single dense sentence with parenthetical chains ('builds: a candidate to close; failing; waiting; removed; ...') that is harder to parse than it needs to be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and all five parameters documented in the schema, the description supplies enough context about data provenance and field semantics for correct invocation; missing only explicit sibling routing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description goes further by explaining what verdict values mean in context ('builds: a candidate to close', 'whether nixpkgs has the version asked'), adding semantic meaning beyond the flat enum list.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Search nixpkgs' open issues by title') and immediately scopes it by the two issue kinds the tool covers. It does not name the nearest siblings (build_failures, update_attempts) to say how it differs from them, which keeps it below a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the descriptions of the two kinds and their fields, but there is no explicit when-to-use or when-to-prefer-a-sibling guidance despite overlapping siblings like build_failures and update_attempts being present.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
needs_attentionPackages needing attentionARead-only
Packages that need attention, as nixkeeper's dashboard counts them: a build failing on Hydra, outdated, vulnerable, or a CVE fix to backport; optionally only one maintainer's (GitHub handle), one team's or one list's, one kind, one platform. Without maintainer, team or list: all of nixpkgs (thousands: narrow with kind). With a maintainer or team, also the open PRs they can merge now with the merge bot (canMerge).
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | any (default): what the dashboard says needs attention; failing (a build of its own fails), updateFailing (the update bot fails), outdated, waiting (updated on master, waiting for the channel), vulnerable, backport, broken; stagingNext: builds on master but fails its own build on staging-next (a forecast: it fails on master when staging-next is merged, unless fixed; not in any); all: every package of the maintainer/team/list. | |
| list | No | One of the dashboard's lists. | |
| team | No | A nixpkgs team (Gaming, Qt-KDE, ...). | |
| limit | No | At most this many results (default 50). | |
| query | No | Instead of the others: the dashboard page's search, as its box takes it (is:builds on:darwin team:Gaming wine). is: one card (outdated, failed, builds, updates, vulnerable, backport, broken, staging-next-breaks), is:unbuilt, -is:broken, has:pr, -has:pr, -has:maintainer, on:linux or on:darwin, in: a package set (python313Packages, top-level), team:, by: or @handle, and words of a name. Without is:, every package of the maintainer's or team's, as the page lists them. Other words (age:, sort:...) are refused; the answer's query.page links the page with the query. | |
| platform | No | linux or darwin: available there (for failing: failing there). | |
| maintainer | No | A maintainer's GitHub handle. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, and the description adds real context beyond them: cross-parameter behavior (maintainer/team silently widen results to include canMerge PRs), the stagingNext forecast semantics, and that unsupported query words are refused with a query.page link returned. No auth or rate-limit notes, but the behavioral picture is substantially richer than the annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and the all-of-nixpkgs caveat are front-loaded, which is good, but the three sentences are long and clause-heavy, and much of the query grammar (is:, on:, team:, by:, refused sort:/age:) duplicates what the schema already says. Trimming the restated query syntax would make it tighter without losing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter, all-optional, no-output-schema tool, the description covers defaults (limit 50, kind any), the narrowing strategy, and cross-parameter side effects, and hints at the response shape via 'the answer's query.page'. What is missing is any statement of what a single package entry contains, which matters since no output schema exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds semantics the schema does not encode: the interaction where maintainer/team also surface open mergeable PRs, and the 'instead of the others' relationship of query to the filter parameters. That justifies going above baseline, though most per-parameter detail is a restatement of the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific resource and scope: 'packages that need attention, as nixkeeper's dashboard counts them', and enumerates the concrete categories (failing, outdated, vulnerable, backport) that define the set. That framing separates it cleanly from siblings like build_failures, vulnerabilities, or find_packages, which each cover only one slice.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit operational conditions: without maintainer/team/list you get all of nixpkgs (thousands), so narrow with kind; with a maintainer or team you additionally get mergeable PRs. It also states the query parameter is an alternative to the filters. It stops short of naming sibling tools to use instead, so not a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
overviewnixpkgs overviewARead-only
All of nixpkgs at a glance, from nixkeeper's dashboard: how many packages are outdated, failing to build, failing their update attempts, vulnerable, broken; the newest and longest-standing of each; the failing dependencies blocking the most builds; why builds and the update bot fail, grouped; what was fixed in the last week.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so safety is covered. Beyond that, the description does real work by characterizing the response as counts plus notable exemplars ('how many ... the newest and longest-standing of each', 'blocking the most builds', 'grouped'), which with no output schema is the only signal about what the call returns. It does not mention data freshness or cost, but the aggregation behavior is disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, front-loaded with the scope ('All of nixpkgs at a glance'), followed by a semicolon-delimited inventory of metrics. Dense but each listed category earns its place by defining the dashboard's coverage. Slightly list-heavy, but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and no parameters, the description carries the burden of explaining what comes back, and it largely does so by enumerating the metrics and the notable-item pattern. The main omission is guidance on how this aggregate relates to the sibling tools that cover the same categories in detail. Given the low structural richness of the tool, coverage is close to sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing to document and the baseline is 4. The description adds no parameter information because none exists, which is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a clear purpose: an aggregate 'all of nixpkgs at a glance' dashboard, and enumerates the specific metrics it surfaces (outdated, failing builds, vulnerabilities, blocking dependencies, recent fixes). An agent can tell this is the summary view rather than a per-package lookup. It stops short of naming which siblings it supersedes, so differentiation from the many overlapping category tools (build_failures, vulnerabilities, needs_attention) is left implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'At a glance' implies this is the entry-point summary, and the enumerated contents imply it aggregates what siblings expose individually, but the description never states when to use this versus find_packages, build_failures, or vulnerabilities. No exclusions, no prerequisites, no ordering guidance is given. Usage is only implied by the aggregate framing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
packageA package's stateBRead-only
Everything nixkeeper knows about one nixpkgs package: its nixpkgs version against upstream's (Repology, nixkeeper's own update checks), master's version, Hydra's latest builds on each platform with why a failure failed and when it last built, the update bot's (nixpkgs-update, r-ryantm) latest attempt and when it tries next, open update PRs and other PRs and issues, CVEs and advisories with nixkeeper's verdict against nixpkgs' version, maintainers and teams; an update merged into staging or staging-next on its way to master (stagingPR, and how it builds there), and whether staging-next breaks the package (stagingNextBreaks: a forecast). newerInDigests: what the hourly digests have that's newer than the dashboard's last sync.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Its attribute (wesnoth, python313Packages.requests); python3Packages works too. | |
| repology | No | Every repository's version from Repology, not only nixpkgs' and the newest. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds meaningful context about data provenance and freshness (Repology, hourly digests, Hydra last-built timestamps, forecasts like stagingNextBreaks) that goes beyond annotations, but says nothing about whether the call is expensive or how stale data can be.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is front-loaded correctly with the core purpose in the first clause, and the semicolon list does group related fields. However the whole description is a single sprawling sentence that is hard to parse, and the dense enumeration could have been shortened with a clearer hierarchy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, this description is the only source of return-value information, and it enumerates the returned fields thoroughly (builds, PRs, CVEs, maintainers, staging forecasts). The main gap is that it never routes the agent from find_packages to this tool or states prerequisites.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents both parameters, including the attribute syntax and the python3Packages alias. The description adds no format or edge-case detail about name or repology beyond what the schema provides, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening clause states the resource precisely ('one nixpkgs package') and the scope ('everything nixkeeper knows'), which an agent can distinguish from aggregate siblings like overview or needs_attention. It never names a verb (get/fetch/detail), but the lookup intent is unambiguous from the description and the single required name parameter.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use guidance and no sibling is named as an alternative. The reader must infer that find_packages searches while this one details a single package; the relationship is never stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pull_requestsOpen nixpkgs PRsARead-only
Search nixpkgs' open pull requests (the PR digest, hourly), with what the digest makes of each: its buckets (update, init, drop, tiny, bot, python, ...), the update it makes and how it compares with nixpkgs now (state), whether a maintainer can merge it with the merge bot, whether it blocks the update bot, duplicates, and packages it touches that fail on Hydra (maybe its fix).
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | The branch it targets (master, staging, ...). | |
| sort | No | updated (default) or created, newest first. | |
| limit | No | At most this many results (default 30). | |
| state | No | superseded (nixpkgs already has it: close it), overtaken, downgrade, snapshotToRelease, preRelease. | |
| author | No | The author's GitHub login. | |
| bucket | No | update, init, drop, by-name, tiny, bot, ci-bot, python, haskell, node, nixos, lib, ci, docs, treewide, version-only, cve. | |
| drafts | No | Include drafts (default true). | |
| search | No | Part of the title. | |
| package | No | PRs touching it: by its title ("foo: 1.0 -> 1.1"), its update, or its pkgs/by-name directory. | |
| can_merge | No | A maintainer's GitHub handle: only the PRs they can merge now with the merge bot (ready, not a draft, no conflict, no changes requested, and they maintain every package it touches). | |
| merge_bot | No | eligible: a maintainer can merge it with the merge bot; ready: and its CI is green. | |
| blocks_bot | No | Only those stopping the update bot's next update. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds genuinely useful context beyond that: the data is digest-derived and refreshed hourly, and the values are the digest's own judgements rather than raw GitHub state. It does not discuss pagination or result ordering beyond what the schema says.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the verb and resource, then the return semantics. It is one long colon-and-parenthetical sentence, which is dense but every clause carries information; only the trailing 'maybe its fix' aside is loose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 12 optional parameters and no output schema, the description does useful work by naming the result fields the caller will receive (buckets, state, merge-bot eligibility, duplicate flags, Hydra failures). Combined with annotations covering read-only behavior, an agent has enough to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 12 parameters including enum meanings. The description largely restates those same lists (buckets, merge bot) and only mildly enriches the concept of 'state' as a comparison with current nixpkgs. Baseline 3 applies when the schema carries the load.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — 'Search nixpkgs' open pull requests' — scoped to the hourly PR digest, and enumerates the judgement fields it returns. It is clearly distinct from siblings like issues or find_packages by resource, though it never names an alternative explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the parameter list (bucket, state, can_merge, blocks_bot) suggests the triage scenarios it supports, but there is no explicit 'use this when / use X instead' guidance or statement of prerequisites. The agent must infer the intent from the field inventory.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_attemptsUpdate bot attemptsBRead-only
nixpkgs-update's (r-ryantm) latest attempt at packages (the update-bot digest, every 3 hours): its outcome, versions, PR, why it failed with a log excerpt; for one package, also its place in the bot's queue and when it's expected to try again.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | At most this many results (default 30). | |
| since | No | Only since then: "24h", "7d", "2w", or a day or time (ISO 8601). | |
| reason | No | Why a failed attempt failed: bot, unavailable, patch, dependency, hash, source, updateScript, tests, noLog, build, request, other. | |
| search | No | Part of an attribute. | |
| outcome | No | prOpened, prExists, branchExists, noChange, cantUpdate, skipped, failed, other. | |
| package | No | One attribute, as the bot names it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds useful behavioral context the annotations do not: the data is a digest refreshed every 3 hours, and single-package queries additionally surface queue position and next retry estimate. It does not address auth, rate limits, or how the many filters combine.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a single compact sentence, front-loaded with the data source, with no filler. The semicolon-clause structure is dense and slightly run-on, and the absence of a leading verb makes the action itself less immediately scannable, keeping it short of a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully enumerates what a result carries (outcome, versions, PR, failure reason with log excerpt, plus queue/retry for a single package) and notes the 3-hourly refresh. Combined with complete schema coverage for all six filters and read-only annotations, this is nearly everything an agent needs, though it never explains default behavior or how filters interact.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds genuine meaning for the `package` parameter by explaining that querying one attribute also yields the bot's queue placement and expected retry time, which the schema's 'One attribute, as the bot names it' does not convey. The other five parameters (limit, since, reason, outcome, search) are left entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description identifies the specific resource (nixpkgs-update / r-ryantm's latest attempt per package, the 3-hourly digest) and what it contains, so an agent can infer this tool queries the update bot's attempt records. It lacks an explicit verb (it reads as a data dictionary entry rather than 'Get...') and never contrasts itself with siblings like build_failures or pull_requests, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no condition that selects this tool over siblings such as build_failures or needs_attention, and no mention of prerequisites. The only hint of a usage mode is the incidental note that queries for one package also return queue position, which is not framed as guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vulnerabilitiesVulnerabilitiesARead-only
CVEs from the NixOS security tracker (with its issue, severity, affected versions, status on master and the release branches) and OSV advisories for language packages (the vulnerabilities digest, hourly): one package's, one CVE's (or NIXPKGS-..., or an advisory id), or else the CVEs affecting some package now, worst first.
| Name | Required | Description | Default |
|---|---|---|---|
| cve | No | CVE-..., NIXPKGS-..., GHSA-..., PYSEC-... | |
| limit | No | At most this many results (default 30). | |
| package | No | An attribute. | |
| severity | No | critical, high, moderate/medium, low. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds real context beyond that: data provenance (NixOS tracker + OSV advisories), update cadence ('hourly' digest), and result ordering ('worst first'). The phrasing about the digest is murky, keeping it from a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Everything is packed into a single run-on sentence with heavy parenthetical nesting, and phrases like 'the vulnerabilities digest, hourly' are hard to parse. The core purpose is front-loaded, but the structure could be considerably cleaner.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description helpfully pre-announces what each record contains (issue, severity, affected versions, master and release-branch status), which compensates for the missing return documentation. Combined with the query modes and default ordering, an agent has enough to call it correctly, though edge cases (e.g., combining severity with package) are unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds value above baseline by describing default behavior when no parameters are supplied (CVEs affecting packages, worst first) and by mapping the query modes onto the parameters. It does not, however, explain parameter interaction or precedence explicitly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource precisely (CVEs from the NixOS security tracker plus OSV advisories for language packages) and enumerates the three query modes: one package's CVEs, one CVE/advisory id, or CVEs affecting a package sorted worst-first. This clearly separates it from siblings like issues or build_failures. It stops short of naming any sibling tool, so it earns a 4 rather than a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The three query modes imply when each parameter applies, but there is no explicit when-to-use/when-not guidance and no routing to or from alternatives like issues or find_packages. Usage is inferable but left to the agent to reconstruct.
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 tool update
v0.5.1- Changed
needs_attention1 field changed- added
Input schema / properties / queryAdded value: +{ + "description": "Instead of the others: the dashboard page's search, as its box takes it (is:builds on:darwin team:Gaming wine). is: one card (outdated, failed, builds, updates, vulnerable, backport, broken, staging-next-breaks), is:unbuilt, -is:broken, has:pr, -has:pr, -has:maintainer, on:linux or on:darwin, in: a package set (python313Packages, top-level), team:, by: or @handle, and words of a name. Without is:, every package of the maintainer's or team's, as the page lists them. Other words (age:, sort:...) are refused; the answer's query.page links the page with the query.", + "type": "string" +}
1 tool update
v0.4.1- Changed
issues1 field changed- changed
Input schema / properties / package / descriptionPrevious value: -"Issues about it: the package a build failure or update request names, or every word of its name in the title."New value: +"Issues about it: the package a build failure or update request names, or its name whole in the title (not pkg-config for pkg)."
10 tool updates
v0.3.0- First observed
build_failures - First observed
data_status - First observed
find_packages - First observed
issues - First observed
needs_attention - First observed
overview - First observed
package - First observed
pull_requests - First observed
update_attempts - First observed
vulnerabilities
TDQS
Scored across 10 tools
Most tools target clearly different resources or actions: find_packages searches, package retrieves one package, issues and pull_requests cover distinct artifact types, and vulnerabilities and update_attempts are specialized. There is some conceptual overlap among overview, needs_attention, and build_failures because all surface problematic packages/builds, but the detailed descriptions mostly make the boundaries usable.
All names use snake_case, but the convention is mixed: find_packages is verb_noun while package, overview, issues, vulnerabilities, pull_requests, build_failures, needs_attention, data_status, and update_attempts are noun/resource phrases. Singular/plural usage also varies (package vs issues/pull_requests), so the pattern is readable but not strongly predictable.
Ten tools is well within a reasonable range and fits the server's monitoring scope. Each tool covers a distinct area of nixpkgs health: package lookup/detail, build failures, dashboard summaries, issues, PRs, vulnerabilities, update-bot attempts, and data freshness.
The surface covers the main read-only monitoring lifecycle: package discovery and detail, aggregate health, attention lists, build failures, issues, PRs, CVEs/advisories, update attempts, and digest freshness. Minor gaps exist around deeper direct issue/PR detail or explicit maintainer/team listing, but core workflows appear covered.
Maintenance
Related MCP Connectors
CVE lookups (NVD) and dependency-manifest audits (OSV) for AI agents. No API keys.
CVE lookups (NVD) and dependency-manifest audits (OSV) for AI agents. No API keys.
Package intelligence for AI agents across npm, PyPI, crates.io and deps.dev. No API keys.
Package intelligence for AI agents across npm, PyPI, crates.io and deps.dev. No API keys.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAccess the Nix ecosystem (Nixpkgs, NixOS, Home Manager, nix-darwin, nixvim, nixhub...)7GPL 3.0
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to interact with NixOS development tools, manage builds, and optimize workflows through natural language.Apache 2.0
- AlicenseNot gradedqualityBmaintenanceExposes code-review and issue-triage tools to AI assistants over stdio, letting them evaluate unified pull-request diffs for maintainer remarks, slice diffs into categorized AST hunks, and classify GitHub issues by priority while synthesizing minimal reproduction stubs.1Apache 2.0
- AlicenseNot gradedqualityCmaintenanceEnables an AI assistant to retrieve IT system status and search or rebuild a vector-indexed knowledge base of operational runbooks. It supports local, tool-grounded responses over stdio for Ollama-based agents, helping prevent hallucinated IT operations guidance.MIT