@mgcrea/mcp-npm
An MCP server for the npm registry that is read-only by default and can be enabled to manage trusted publishing, packages, access, orgs/teams, tokens, and publishing.
Auth: Check auth status (
npm_auth_status), who you are (npm_whoami), and manage OTP prompts/cache (npm_auth_otp,npm_auth_clear_otp).Security auditing: Audit installed package versions against npm advisories with no token needed (
npm_audit_dependencies).Trusted publishing: Read, set, batch-set, and delete OIDC trusted publishers on packages (writes require
NPM_ALLOW_WRITES=1; delete also needsconfirm: true).Package intel: Get package metadata, specific versions, version lists, and search packages.
Dist-tags: List, add, and remove dist-tags (add/remove are guarded writes).
Downloads: Get download stats for packages and versions.
Access control: Check package visibility, list collaborators, set package access, and deprecate packages (writes guarded).
Publishing: Publish and unpublish packages (guarded, with confirmation).
Orgs: List org members, teams, packages; change member roles; remove members (writes guarded).
Teams: List team members/packages; create/delete teams; add/remove members; grant/revoke package access (writes guarded).
Tokens: List tokens; create tokens (value shown once); revoke tokens (guarded).
Escape hatch: Raw
npm_requestfor arbitrary registry calls.Read-only by default: Write tools are not registered unless
NPM_ALLOW_WRITES=1; destructive actions also require explicit confirmation.
Provides tools for interacting with the npm registry, enabling package metadata lookups, searching, dist-tag management, deprecation, access control, org and team governance, token management, security advisories, downloads, and package publishing, including programmatic configuration of trusted publishers.
Click on "Install 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., "@@mgcrea/mcp-npmShow me the latest version and dist-tags for express."
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.
@mgcrea/mcp-npm
A Model Context Protocol server for the npm registry, built around the thing npm's own tooling makes hardest to automate: configuring trusted publishers. It also covers package intel, dist-tags, deprecation, access, org and team governance, tokens, security advisories, and publishing. Read-only by default — the mutating tools are not registered at all unless you turn them on.
Features
Trusted publishing, programmatically. Read, set and revoke the OIDC trusted publisher on a package, or apply one across a batch of packages with a single browser authorization.
Works with zero configuration. If
npm whoamianswers, so does this — it reads the tokennpm loginalready wrote to~/.npmrc, scoped to the registry you are actually talking to.Read-only by default. Write tools are absent, not refused, until
NPM_ALLOW_WRITES=1. Everything irreversible additionally needs an explicitconfirm: true.Never exits on missing credentials. An unconfigured server still answers, and
npm_auth_statustells you exactly what to set.Responses shaped for a context window. A raw packument is megabytes; these are a screen.
Native
fetch, no runtime dependencies beyond the MCP SDK and Zod.
Related MCP server: npm-registry-mcp
Security
Supply chain. Two runtime dependencies: @modelcontextprotocol/server and zod. No HTTP
client, no logging framework. Every transitive dependency would be attack surface on a process
holding a live npm token.
Your credentials. The token is read from NPM_TOKEN, a config file, or the entry in
~/.npmrc matching the configured registry — a token for npmjs.org is never sent to a
private registry, or the reverse. Nothing is written to disk. One-time passwords are held in
memory only, for the life of the process.
Blast radius. With the defaults, this server can only read. With NPM_ALLOW_WRITES=1 it can
change what your CI is allowed to publish, move dist-tags, deprecate versions, alter org and team
membership, mint and revoke tokens, and publish or unpublish packages. Grant it deliberately.
Token choice matters. A granular access token with Bypass 2FA enabled is rejected by every trusted-publisher write. See Traps worth knowing.
Configure
The server starts with no configuration at all. In that state it registers only the tools
that need none — npm_auth_status and npm_audit_dependencies, since npm's advisory endpoint
takes no authentication — and npm_auth_status tells you what to set for the rest. It never
refuses to start over a missing token, because an MCP server that exits shows up in the client
as a bare Connection closed with the explanation swallowed.
Most people need nothing:
npm login # this server reads the resulting ~/.npmrc entry
npm whoami # if this answers, you are configuredVariable | Required | Description |
| no | Overrides the |
| no | Defaults to |
| no | Defaults to |
| no |
|
| no |
|
| no | A code. Almost always wrong — see the note in |
| no | How long a confirmed code is reused. Defaults to |
| no | Calls one code covers. Defaults to |
| no |
|
| no | Retry budget for 429/5xx. Defaults to |
| no | Path to npm's |
| no | Path to a JSON config file. |
| no |
|
See .env.example for the annotated list.
Config file
The environment wins, field by field. A config file supplies whatever the environment does not, so Docker and CI keep working, and a one-off
NPM_ALLOW_WRITES=0still overrides a file that saystrue.Keys are camelCase (
allowWrites, notNPM_ALLOW_WRITES).Unknown keys are an error, not ignored — a typo'd
allowWritetells you so instead of silently falling back to the environment.Location:
$NPM_MCP_CONFIG, else$XDG_CONFIG_HOME/npm-mcp/config.json, else~/.config/npm-mcp/config.json. An absent file is fine; a malformed one is reported with its path. The variable isNPM_MCP_CONFIG, notNPM_CONFIG, because npm reads its ownnpm_config_*namespace out of the environment.The server warns on stderr if the file is readable by other users.
Quick start
A. npx
{
"mcpServers": {
"npm": { "command": "npx", "args": ["-y", "@mgcrea/mcp-npm"] }
}
}B. Docker
docker run --rm -i -e NPM_TOKEN ghcr.io/mgcrea/mcp-npmC. From source
pnpm install && pnpm build
node dist/cli.jsInspect the tools
npx @modelcontextprotocol/inspector node dist/cli.jsTwo-factor, and why this cannot be fully unattended
npm requires an npm-otp header on all three trusted-publisher endpoints — including the
read — and a one-time password lasts about five minutes. A code cannot be configured once at
startup and reused: it is dead before anything runs. Fully unattended trusted-publisher
configuration is not possible, and npm_auth_status reports that rather than offering a
setting that looks like it should work.
What is possible is spending one authorization on many packages. npm's confirmation page has a
same-IP cooldown; this server caches the confirmed code for that window (in memory, never on
disk) so npm_set_trusted_publisher_batch prompts once for up to 25 packages.
The flow, when npm asks:
A trust call goes out without a code and npm answers
401with an authorization URL.The server opens that URL and waits for you to approve it.
The call is retried with the confirmed code, and the code is cached for the window.
Run npm_auth_otp first if you would rather approve the prompt at a moment of your choosing —
before a long batch, say. Pass it a code from an authenticator app to skip the browser
entirely, or open: false when the browser is on another machine.
Tools
41 tools. W = needs NPM_ALLOW_WRITES=1; ⚠ = also needs confirm: true.
Area | Tools |
Auth |
|
Trusted publishing |
|
Packages |
|
Dist-tags |
|
Downloads |
|
Security |
|
Access |
|
Publishing |
|
Orgs |
|
Teams |
|
Tokens |
|
Escape hatch |
|
Worked example: trusted publishing across a fleet
The problem this server was written for. You have several packages published from one repo, and npm's UI wants you to configure each by hand.
First, check you can:
npm_auth_statustrusted_publishing_available must be true. If it is not, blockers says why — the usual
answers are a bypass_2fa token or 2FA not enabled on the account itself.
See what one package has today:
npm_get_trusted_publisher package="@mgcrea/mcp-ovh"This is the call that triggers the browser confirmation, because npm requires an OTP even to read. Approve it once.
Now preview the whole batch — nothing is written:
npm_set_trusted_publisher_batch
packages=["@mgcrea/mcp-npm", "@mgcrea/mcp-ovh", "@mgcrea/mcp-x"]
provider="github"
repository="mgcrea/mcp-npm"
workflow_filename="ci.yml"
dry_run=true
confirm=trueThen drop dry_run. Packages already configured correctly come back as unchanged and cost
nothing. Verify against npm's own CLI, which calls the same endpoint:
npm trust list @mgcrea/mcp-ovhWith that in place, CI publishes with no token anywhere:
permissions:
contents: read
id-token: write # this is what OIDC trusted publishing needs
# ...
- run: npm publish --provenance --access publicTraps worth knowing
A "Bypass 2FA" granular token is refused by every trust write (403, pointing at
gh.io/npm-gat-bypass2fa-deprecation). Reads keep working, so it only surfaces on the write. Create a token without that option, or use a session token fromnpm login.Two-factor must be on the npm account, not just the token. No token setting substitutes.
Several governance reads accept only a session token.
npm_list_tokens,npm_list_org_members,npm_list_collaboratorsandnpm_get_package_visibilityrefuse a granular access token — so a read can fail where the matching write succeeds. This is the failure someone who followed npm's own "use granular tokens" advice will hit.One trusted publisher per package, and no update endpoint. Changing one is genuinely delete-then-create.
npm_set_trusted_publisherowns both steps for a reason: split apart, a failed create after a successful delete leaves the package with no publisher and a broken release pipeline.workflow_filenameis a bare filename.ci.yml, never.github/workflows/ci.yml.Scoped names are escaped two different ways.
/@babel%2fcorefor the packument,%40babel%2Fcorefor the/-/package/routes. The wrong one returns 404, which reads like "no such package".Bulk downloads rejects scoped packages, caps at 128, and cannot do a daily series. The single-package form handles
@scope/namefine.**Deprecating with an empty message undeprecates.**
npm_create_tokenshows the value once. It is never retrievable again, only revocable.npm_publishproduces no provenance attestation. A CI publish over OIDC does. Prefer it.npm publishes no rate-limit headers, and documents no per-endpoint numbers — only that 5M requests/month is acceptable. Assume nothing; the batch tool paces itself at 2s.
Troubleshooting
A tool I expected is missing. Call npm_auth_status. An absent tool almost always means
missing configuration or NPM_ALLOW_WRITES being off — write tools are not registered at all
when it is unset, by design.
Connection closed in the client. Run the binary by hand with the same environment; the
error the client swallowed is on stderr.
Every trust call 403s. Read the remedy field on the error. The three causes are a
bypass_2fa token, 2FA not enabled on the account, and not being a maintainer.
The browser prompt keeps reappearing. The cached code is being minted for a different npm
account than the token belongs to. npm_auth_clear_otp, then check npm_auth_status names the
account you expect.
Develop
pnpm install
pnpm lint && pnpm format:check && pnpm typecheck && pnpm test && pnpm buildCheck the built server still speaks the protocol and gates what it should:
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"cli","version":"0"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
| node dist/cli.js 2>/dev/null | jq -r '.result.tools[]?.name'Publish
pnpm dlx release-it # bump, commit, tag
git push --follow-tags # CI publishes to npm and GHCR from the tagCI publishes over OIDC trusted publishing with provenance, so no npm token exists anywhere.
License
MIT — see LICENSE.
Available Tools
2 toolsnpm_audit_dependenciesnpm: Audit DependenciesARead-only
Check a set of package versions against npm's security advisories — the same data npm audit uses, queried directly. Takes a flat map of package name to the versions you have installed, and returns only the packages with advisories against them. Needs no npm token, so it works on an otherwise unconfigured server. The references field is stripped from each advisory: it is about 1.5 KB of markdown links apiece, and url already points at the write-up.
| Name | Required | Description | Default |
|---|---|---|---|
| dependencies | Yes | Installed versions per package, e.g. {"lodash": ["4.17.20"], "minimist": ["1.2.0", "0.0.8"]}. Exact versions, not ranges — an advisory match is computed against the version you actually have. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses meaningful behavior: it returns only packages with advisories, it strips the `references` field for size, and the `url` field remains as the pointer to the write-up. It also explicitly notes no token is needed, which is valuable operational context.
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?
The description is concise and well-structured: it opens with the core function, then explains input format, operational prerequisite, and a notable output transformation. Every sentence contributes useful information without redundancy.
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 one-parameter, read-only tool with no output schema, the description adequately covers what input is expected, what the output will contain (only affected packages), and one important field behavior that would otherwise be a surprise. An agent can confidently invoke this tool without needing more context.
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 schema has 100% coverage and already explains the format, gives an example, and warns that exact versions (not ranges) are required. The description's phrase 'flat map of package name to the versions you have installed' simply repeats the schema's meaning without adding new semantics, so the baseline 3 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?
The description states a specific verb ('Check') and resource ('package versions against npm's security advisories'), and ties it to the familiar `npm audit` command. The topic is clearly distinct from the sibling `npm_auth_status`, which is about authentication state, not dependency auditing.
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?
It gives clear context: this is a direct query of npm's advisory data, and it requires no npm token, so it works on an unconfigured server. It doesn't explicitly mention the sibling as an alternative, but the sibling's purpose is obviously different, so an agent can infer when to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
npm_auth_statusnpm: Auth StatusARead-only
Report what this server can and cannot do: whether a token is configured and where it came from, which npm account it belongs to, whether two-factor authentication is on, whether writes are enabled, and whether a one-time password is currently cached. Call this first when a tool you expected is missing — an absent tool means missing configuration rather than a bug. The trusted_publishing_available field and its blockers list answer, without spending a call, whether the trusted-publisher tools can work at all.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already signals a safe read. The description adds valuable behavioral nuance beyond that: that a missing sibling tool should be interpreted as a configuration gap, not a bug, and that the `trusted_publishing_available` field can answer capability questions 'without spending a call.' This makes the tool's role and interpretation explicit.
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?
The description is two sentences, front-loaded with the core reporting function, then gives targeted diagnostic guidance. No wasted words; every sentence adds information about what the tool reveals or when to use it.
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, the description covers the main output areas and even names a key field (`trusted_publishing_available`) and its `blockers` list. Slight gap: no full response format is given, and with no output schema, a bit more detail on response shape would make it fully self-contained. Still, the essentials are present.
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?
There are zero parameters, and the input schema is empty, so there is nothing for the description to add at the parameter level. The description correctly focuses on outputs and usage rather than inventing parameter detail. A zero-parameter tool earns the baseline score of 4.
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 begins with a precise verb and object: 'Report what this server can and cannot do,' then enumerates the exact dimensions covered (token configuration, account, 2FA, write access, cached OTP). This is unmistakably an auth/status diagnostic tool and leaves no ambiguity about its role relative to the sibling audit tool.
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?
It gives explicit guidance: 'Call this first when a tool you expected is missing — an absent tool means missing configuration rather than a bug.' It also instructs when to consult specific output fields, which is actionable. There are no alternatives or exclusions, but the diagnostic context is clear enough to warrant a 4.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
The two tools have entirely distinct purposes: one reports authentication/configuration state, the other checks package versions against security advisories. An agent cannot plausibly confuse them when selecting a tool.
Both names share the `npm_` prefix and use snake_case, which makes them feel cohesive. However, `npm_audit_dependencies` is verb-object while `npm_auth_status` is noun-noun, a minor deviation from a fully parallel naming convention.
With only two tools, the server sits at the thin end of the typical range. Each tool is substantive, but an npm-focused server would usually need more surface area to feel well-scoped.
The pair gives a useful auth diagnostic and a security audit, but leaves no action path for an agent—there are no package lookup, publish, or remediation tools. The auth status tool also references write and trusted-publisher capabilities that are not exposed, leaving a significant gap for a server called npm.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Provide AI-powered real-time analysis and intelligence on NPM packages, including security, depend…
Package intelligence for AI agents across npm, PyPI, crates.io and deps.dev. No API keys.
Dive into the world of npm with our NPM Package Info MCP. Access crucial metadata about any npm
A registry of AI agent tools — MCP servers, APIs, CLIs, SDKs — kept current by automated ingestion.
Related MCP Servers
- AlicenseAqualityAmaintenanceEnables npm registry operations from MCP clients like Claude Code and Cursor, with 64 tools for package intelligence, security audits, dependency analysis, org/team management, and write operations like deprecate and unpublish.643622MIT
- FlicenseNot gradedqualityCmaintenanceGrants AI agents real-time access to the NPM registry, enabling package metadata retrieval, version checks, and dependency auditing for up-to-date code generation.213
- AlicenseNot gradedqualityDmaintenanceProvides AI assistants with tools to check npm package versions and security heuristics, including version lookups, signal-based analysis, and batch analysis of package.json files.15AGPL 3.0
- AlicenseAqualityCmaintenanceEnables AI coding agents to search the npm registry and retrieve package metadata, READMEs, download stats, GitHub details, and usage snippets via the Model Context Protocol.921MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/mgcrea/mcp-npm'
If you have feedback or need assistance with the MCP directory API, please join our Discord server