@mgcrea/mcp-totp
Provides TOTP verification codes for npm 2FA, enabling automated npm publishing and account management without manual code entry.
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-totpget the current TOTP code for npm"
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-totp
Model Context Protocol server that mints TOTP verification codes on macOS, with the seeds kept in the login keychain.
It exists so that npm publishing — and anything else gated behind a six-digit code — can run without a human clicking an approval every five minutes.
What this is NOT
It cannot read verification codes out of Passwords.app. No interface for that exists, and this is worth stating plainly because it is the first thing everyone assumes:
Route | Why not |
AppleScript | Passwords.app has no scripting dictionary — |
App Intents / Shortcuts | No |
| Registered, but inbound only — it imports a seed, it never emits a code |
| No OTP subcommand, and its legacy API cannot see synchronizable iCloud items at all |
A helper using | Passwords.app reads TOTP through the |
Reading | Readable as a file, encrypted under Secure-Enclave-wrapped class keys |
UI scripting | Needs Accessibility and Automation grants and still raises a Touch ID prompt per reveal — so not automation |
So this server keeps its own copy of the seed and computes codes locally. What it does
offer is the other direction: totp_import_uri can hand the same seed to Passwords.app
through the otpauth:// scheme it claims, so your phone and Mac keep working normally and
nothing drifts out of sync.
Related MCP server: proton-pass-community-mcp
Security
Read this before deciding to use it.
Storing a TOTP seed on the machine that also holds the credential it protects means
automation on that machine is effectively single-factor. Anything that can read the
keychain item can mint codes forever. That is the deliberate trade for unattended publishing,
and it is why every seed-writing tool sits behind TOTP_ALLOW_WRITES.
Two narrower properties worth knowing:
Seeds are passed to
securityin argv, becauseadd-generic-passwordhas no stdin form — its only alternative is an interactive tty prompt. A local process watchingpscould catch one during the milliseconds a write takes.The item's ACL trusts
/usr/bin/security, which is what makes reads silent rather than prompting. It also means anything on the machine that can runsecuritycan read the seed.
If you do not need unattended operation, you probably do not need this. For npm specifically, trusted publishing over OIDC needs no second factor at all — configure that first, and use this only for local publishes and account management.
Configure
Variable | Meaning |
|
|
| A seed supplied by environment, for Docker/CI where there is no keychain. Either an |
| Keychain service the seeds are filed under. Defaults to |
| Verbose stderr logging |
Seeds resolve environment first, then keychain, per label — so a TOTP_SECRET_NPM in a
container beats whatever the machine holds, without editing anything.
Labels are lower-case letters, digits and underscores, starting alphanumeric (npm,
aws_root). That restriction is load-bearing: it keeps the mapping to TOTP_SECRET_<LABEL>
bijective, so a label you see listed is a label you can look up.
Quick start
A. npx
{
"mcpServers": {
"totp": {
"command": "npx",
"args": ["-y", "@mgcrea/mcp-totp"],
"env": { "TOTP_ALLOW_WRITES": "1" }
}
}
}B. From source
pnpm install && pnpm build
TOTP_ALLOW_WRITES=1 node dist/cli.jsInspect the tools
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"ci","version":"0"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
| node dist/cli.js 2>/dev/null | grep -o '"name":"totp_[a-z_]*"' | sort -uTools
W = requires TOTP_ALLOW_WRITES=1. ⚠ = requires confirm: true.
Tool | Purpose | |
| What the server can do, which seeds exist, and the setup guide as data | |
| Registered seeds and their parameters. Never a secret | |
| Mint the current code for a label | |
| W | Store a seed from an |
| W | List the OTP-bearing entries of a Passwords.app CSV export. Returns no passwords, notes or secrets |
| W | Import one entry from that export, by index |
| W ⚠ | Permanently delete a seed |
Getting a seed in
Primary path — never writes every password to plaintext. When a service first hands you the seed, capture it then:
npm profile enable-2fa auth-and-writes # prints an otpauth:// URI
→ totp_import_uri { label: "npm", uri: "otpauth://...", share_with_passwords_app: true }The same seed lands in the keychain and in Passwords.app, so nothing about your normal flow changes.
Secondary path — when you do not want to rotate the service's 2FA. Export from Passwords.app (File › Export All Passwords…, which needs the UI and a biometric confirmation and cannot be driven from here), then:
→ totp_scan_export { file_path: "/Users/you/Passwords.csv" } # pick an index
→ totp_import_from_export { file_path: "...", index: 0, label: "npm" }
→ rm /Users/you/Passwords.csv # it is every credential you haveTraps worth knowing
Modifying a keychain item prompts on first use; creating and deleting do not. On a machine that has not yet granted
/usr/bin/securityaccess to an item,add-generic-password -Uraises an authorization dialog — and with no tty the CLI blocks on it forever, taking the server with it. Once allowed,-Usucceeds silently, so this is a first-use gate rather than a permanent one; that is exactly why it must not sit on the write path, since it fires on a fresh install. Writes here are therefore delete-then-add, which stays inside the two operations that never prompt. Everysecuritycall is also bounded by a 15-second timeout, so a dialog can never wedge the server — it becomes an error that names the dialog instead.HOTP is rejected, not coerced. A counter-based seed minted here would desynchronise the counter held by the real authenticator.
A code returned by
totp_get_codeenters the transcript. It is a bearer-equivalent second factor. Where an integration can read the store directly, prefer that.The keychain item is not a backup.
totp_removeis irreversible; unless the same seed still exists in Passwords.app or on a phone, the account's second factor is gone.
Troubleshooting
A tool is missing. Call totp_auth_status — an absent tool means configuration, not a
bug. The seed tools need a reachable store (macOS keychain, or one TOTP_SECRET_<LABEL>);
the write tools additionally need TOTP_ALLOW_WRITES=1.
A call fails with "timed out after 15s". macOS raised a keychain authorization dialog and is waiting for an answer. Look for it on screen and allow it. Until it is dismissed, every subsequent keychain write is queued behind it.
Connection closed with no tools. Run node dist/cli.js by hand with the same
environment — the startup banner and any error go to stderr, which the client swallows.
Develop
pnpm lint && pnpm format:check && pnpm typecheck && pnpm test && pnpm buildThe correctness proof is test/totp.test.ts: the RFC 6238 Appendix B vectors across SHA-1,
SHA-256 and SHA-512. They are deterministic and need no credentials, and the suite never
touches the real keychain — test/helpers.ts injects an in-memory double.
@mgcrea/mcp-totp/core is a published entry point exposing the dependency-free half (TOTP,
otpauth:// parsing, the keychain store) so other servers can mint codes without loading the
MCP SDK. Nothing under src/core/ may import @modelcontextprotocol/server or zod.
License
MIT
Available Tools
1 tooltotp_auth_statusTOTP: StatusARead-onlyIdempotent
Report what this server can and cannot do: whether a seed store is reachable, which labels are registered and where each one comes from, and whether writes are enabled. Call this first when a tool you expected is missing — an absent tool means missing configuration rather than a bug.
Note what this server is NOT: it cannot read codes out of Passwords.app. No such interface exists — Passwords.app has no scripting dictionary and no App Intents, and its keychain items sit behind an Apple-private access group. This server holds its own copy of the seed and mints codes locally; totp_import_uri can hand the same seed to Passwords.app so both stay in sync.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already state readOnlyHint, idempotentHint, and destructiveHint false, and the description adds behavior beyond those: it explains the server cannot read Passwords.app because no interface exists, and that the server mints codes locally from its own seed copy. This gives the agent critical context about system limitations without contradicting the annotations.
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 front-loaded with the core purpose in the first sentence, then moves to usage guidance and a clarifying limitation. The length is justified because it conveys essential integration context about Passwords.app that would otherwise be invisible to an agent. Every sentence earns its place and no filler is present.
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 enumerates exactly what the agent will learn from the call: reachability of the seed store, registered labels and their sources, and write-enable status. It also covers when to call and what the tool cannot do, making it fully self-contained for an agent to invoke and interpret 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?
The tool has zero parameters and the schema is empty, so there is nothing for the description to add about parameters. The baseline of 4 for a no-parameter tool applies, and the description does not need to compensate for any schema gaps since none exist.
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 opens with a specific verb and resource: it 'reports' the server's capabilities, listing concrete output items such as seed store reachability, registered labels and their origins, and write-enable state. This is unambiguous and cannot be confused with any other operation, especially since there are no sibling tools.
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 explicitly instructs when to call: 'Call this first when a tool you expected is missing — an absent tool means missing configuration rather than a bug.' It also clarifies what the server is NOT and points to totp_import_uri as the relevant alternative for syncing seeds, giving the agent both a trigger condition and a related tool reference.
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. Dates show when Glama detected each change.
1 tool update
v0.1.0- First observed
totp_auth_status
TDQS
With only one tool exposed, there is no possibility of selecting the wrong tool. The tool's purpose as a status/diagnostic endpoint is clearly distinct from any other functionality.
The single tool name uses consistent snake_case and clearly indicates its role as a status report. With no other tools, there is no naming pattern to conflict.
A single status tool is far below the expected scope for a TOTP server, which should include operations for key management and code generation. The description even references a totp_import_uri tool that is not exposed, making the set feel incomplete.
The tool only reports capabilities and configuration state; there are no tools to actually create, import, or use TOTP secrets. This is a severe gap for a server named mcp-totp.
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
Let ChatGPT, Claude & Cursor use your Mac: email, calendar, iMessage, Teams, files. Local, free.
MCP connector for iMessage & Contacts via a local Mac agent + Vercel relay
Connects ChatGPT to your Apple Calendar via a local Mac agent + Vercel relay
Related MCP Servers
- FlicenseNot gradedqualityNot gradedmaintenanceEnables AI agents to perform symmetric and asymmetric encryption of text and files using secure storage in the macOS Keychain. It provides tools for identity management and secure messaging compatible with the CryptoSeed iOS app and CLI.-
- AlicenseBqualityAmaintenanceEnables interaction with Proton Pass via CLI operations, including vault and item management, secret injection, and password generation.472420GPL 3.0
- AlicenseAqualityDmaintenanceEncrypted token store for Claude Code sessions, providing MCP tools for secure secret management with macOS Keychain integration, per-project allowlists, and native dialog input.6166Cryptographic Autonomy 1.0 (Combined Work Exception)
- FlicenseBqualityDmaintenanceEnables macOS automation through 45 AppleScript-powered tools for system control, app management, calendar, reminders, notifications, clipboard, and task scheduling.45-
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-totp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server