Skip to main content
Glama
llmops-pro

albyhub-admin-mcp

albyhub-admin-mcp

Node-admin operations on your Alby Hub, exposed to an LLM agent. MCP server that wraps the Alby Hub HTTP API — read node info, balances, channels, NWC sub-wallets. Where NWC (nwc-mcp) ends (it's wallet-scoped), this server picks up: hub-wide on-chain balance, channel state, sub-wallet inventory.

v0.1 — defensive design. Alby Hub's admin API has evolved across versions and isn't publicly versioned in a stable way. So v0.1 ships one generic proxy tool that hits any path (the escape hatch) plus typed wrappers around a few well-established endpoints. If a typed wrapper's endpoint-guess fails against your Hub version, the proxy lets you discover the right path without re-shipping. v0.2 hardens the typed wrappers once smoke-tested against real Hubs.


The six tools

Tool

Method

Path

Purpose

albyhub_proxy_request

*

*

Generic HTTP proxy — escape hatch for any endpoint not yet wrapped.

albyhub_confirm_request

*

*

Two-step confirm dispatcher for proxy_request.

albyhub_get_node_info

GET

/api/info

Node identity, network, version.

albyhub_get_balances

GET

/api/balances

On-chain + Lightning aggregate balances.

albyhub_list_apps

GET

/api/apps

NWC connections (sub-wallets) provisioned on this hub.

albyhub_list_channels

GET

/api/channels

Lightning channels with status + capacities.

All typed wrappers are safe GETs. Non-GET behavior runs through albyhub_proxy_request, which is gated by ALBYHUB_READ_ONLY and ALBYHUB_REQUIRE_CONFIRM.


Related MCP server: l402-kit-mcp

Requirements

  • Node 20+

  • A running Alby Hub instance (desktop app on http://localhost:8080, or self-hosted exposed somewhere)

  • An Alby Hub API token (Settings → Developer / Apps in the Hub UI)

Install

npx -y albyhub-admin-mcp

Configure

cp .env.example .env
# edit .env: set ALBYHUB_URL (default http://localhost:8080) + ALBYHUB_TOKEN

Required

Var

Purpose

ALBYHUB_URL

Base URL of your Hub. Default http://localhost:8080. Use HTTPS if exposed remotely.

ALBYHUB_TOKEN

API access token. Full-scope tokens can drain the hub's on-chain balance — scope down or use ALBYHUB_READ_ONLY=true if your audience matters.

Optional safety knobs

Var

Default

Purpose

ALBYHUB_READ_ONLY

false

Refuse all non-GET requests via proxy_request. Strongly recommended for first-time setup.

ALBYHUB_REQUIRE_CONFIRM

false

Two-step confirm for non-GET requests.

ALBYHUB_MAX_REQUESTS_PER_MINUTE

30

Rolling 60s rate limit.

ALBYHUB_LOG_PATH

./albyhub-admin-mcp.log

Server log.

ALBYHUB_AUDIT_PATH

./albyhub-admin-mcp-audit.log

Append-only JSON-line audit log.


What if my Hub returns 404 on the typed wrappers?

The endpoint path probably differs in your Hub version. Use albyhub_proxy_request to probe — try /api/node, /info, /api/v1/info, etc. Once you find the right path, you can pin it in your usage (and ping the maintainer to fix the typed wrapper in v0.2).

agent: albyhub_proxy_request({ method: "GET", path: "/api/v1/info" })
→ { status: 200, body: { ... } }   // found it

Safety model

The proxy tool's pipeline:

  1. ALBYHUB_READ_ONLY gate — non-GET requests blocked outright.

  2. Rate limit — rolling 60s window on the requests bucket.

  3. ALBYHUB_REQUIRE_CONFIRM gate — non-GET requests return a token; albyhub_confirm_request executes.

  4. HTTP request — Bearer auth, 15s timeout (override via timeout_ms).

  5. Audit log — every attempt (ok / blocked / error) as one structured JSON line.

GET-only convenience wrappers skip steps 1 + 3 (they're safe by construction) but still go through rate limit + audit.


Companion servers

  • nwc-mcp — wallet ops via NIP-47. Use this for per-sub-wallet spend; use albyhub-admin-mcp for hub-wide / node-level operations.

  • nostr-ops-mcp — NOSTR identity + publishing.

  • marketplace-mcp — NIP-15 marketplace storefront.


License

MIT — see LICENSE.

Contact / Issues

Built by LLMOps.Pro.

  • NOSTR: npub1hdg932jvwc3jdvkqywgqv0ue4nn60exrf92asy8mtazt3hjg7d2s2yw0nw — follow, DM, zap.

  • Lightning Address: sovereigncitizens@getalby.com — for support zaps and "this was useful" tips.

  • Bug reports / feature requests: open a GitHub issue (link forthcoming).

  • Security issues: please disclose privately via NOSTR DM before opening a public issue.

Available Tools

6 tools
albyhub_confirm_requestA

Execute a previously-prepared non-GET request, identified by its one-time token. Only meaningful when ALBYHUB_REQUIRE_CONFIRM=true. The token is consumed (single use) and the safety pipeline (read-only, rate limit) re-runs before the HTTP call.

ParametersJSON Schema
NameRequiredDescriptionDefault
tokenYesConfirmation token from a previous non-GET proxy_request.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must disclose side effects, and it does: the token is 'consumed (single use)' and the safety pipeline re-runs. This gives important context about irreversibility and validation, going well beyond minimal descriptions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences front-load the core action and add necessary conditions and side effects without redundancy. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-parameter tool with no output schema, the description is adequately complete: it explains what the tool does, when it applies, and the key behavioral fact (token consumption). No critical gaps remain for an agent to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already provides a clear description for the token ('Confirmation token from a previous non-GET proxy_request'), giving 100% coverage. The tool description adds extra meaning by noting the token is one-time and tied to a previously-prepared request, enhancing the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function with a specific verb ('Execute') and resource ('previously-prepared non-GET request'). It distinguishes itself from siblings by focusing on confirming/executing an already-prepared request, not on initiating proxy calls or reading node data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states the requirement 'Only meaningful when ALBYHUB_REQUIRE_CONFIRM=true' and implies use after receiving a token from a previous proxy_request. However, it doesn't explicitly name the alternative tool (albyhub_proxy_request) or state when not to use it beyond the condition.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

albyhub_get_balancesA

Fetch hub balances (on-chain + lightning) from GET /api/balances. Distinct from nwc_get_balance — that one is a single sub-wallet's view via NWC; this one is the hub-wide aggregate including on-chain. If your Hub returns 404, probe with albyhub_proxy_request.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are present, so the description carries full behavioral disclosure burden. It clearly states the operation is a read ('Fetch'), describes what is included (on-chain + lightning), and mentions a specific error case (404) with a workaround. While it doesn't cover authentication or response format, it provides meaningful operational context beyond the bare action.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three concise sentences: first states the core function, second differentiates from a sibling tool, third offers a troubleshooting path. Every sentence adds value and is front-loaded with the most important information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no parameters and no output schema, the description fully covers the essential context: what it fetches, the scope (hub-wide), the difference from a similar tool, and what to do if it fails. Nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the input schema fully describes the interface, and the description need not explain parameter details. Per the baseline for 0 params, a score of 4 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'Fetch' with a clear resource 'hub balances' and even names the endpoint 'GET /api/balances'. It also explicitly distinguishes itself from nwc_get_balance, making the tool's purpose immediately clear and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly names an alternative (nwc_get_balance) and explains when to use which: this tool for hub-wide aggregate, that one for a single sub-wallet. It also provides conditional guidance for 404 errors, suggesting albyhub_proxy_request as a fallback, which helps the agent decide between tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

albyhub_get_node_infoA

Fetch Alby Hub node info (identity, network, version) from GET /api/info. Convenience wrapper. If your Hub returns 404 here, the endpoint path differs in your version — use albyhub_proxy_request to probe alternatives like /api/node or /info.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of behavioral disclosure. It reveals the dependent endpoint and warns about version-specific path differences. However, it does not explicitly state that this is a read-only operation (though 'fetch' implies it) or mention any potential side effects, but for a simple info getter this is adequate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences: the first states the core action and result, the second provides fallback guidance. No wasted words, and the most important information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a parameterless convenience wrapper, this is complete. It describes the endpoint, what info is fetched, and handles version discrepancies. No output schema exists, but the description enumerates the key fields (identity, network, version) so the agent knows what to expect.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the schema already fully documents that. The description adds context by indicating what data is returned (identity, network, version), which is useful even without parameters. Baseline for 0 params is 4, and this meets it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool fetches Alby Hub node info (identity, network, version) via GET /api/info. It distinguishes itself from siblings by labeling it a convenience wrapper, making the purpose specific and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says to use this tool for node info and provides a concrete fallback: if a 404 occurs, use albyhub_proxy_request to probe alternative endpoints. This gives clear when-to-use and when-to-use-alternative guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

albyhub_list_appsA

List NWC connections / sub-wallets ('apps') currently provisioned on the Hub. Each entry typically includes name, pubkey, scope, daily budget, and creation timestamp. Hits GET /api/apps. Use this to inventory what's connected to your Hub and what each connection's budget cap is.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden of behavioral disclosure. It explains the underlying API call ('Hits GET /api/apps') and discloses the typical returned fields, including a caveat that entries 'typically' include these, indicating possible variability. While it doesn't explicitly state read-only behavior, the verb 'List' and the lack of side effects implicitly convey this.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core purpose and then enriched with field details and a use case. Every word earns its place; there is no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple, parameterless list tool with no output schema, the description is complete. It specifies the endpoint, typical response contents, and the practical use case. The sibling tools are clearly different (get balances, list channels, etc.), so no further context is needed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters and an empty input schema, so there are no parameter details to clarify. The baseline for 0 params is 4, and the description adds value by describing the output data structure (fields like name, pubkey, scope, daily budget), which compensates for the absence of an output schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists NWC connections/sub-wallets ('apps') on the Hub, using the specific verb 'List' and a precise resource. It also distinguishes itself from sibling tools by mentioning the included fields (name, pubkey, scope, daily budget, creation timestamp) and the use case of inventorying connections and budget caps.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a clear use case: 'Use this to inventory what's connected to your Hub and what each connection's budget cap is.' This implies when the tool is appropriate, though it does not explicitly mention alternatives or when not to use it. Still, it offers direct guidance on the tool's intended scenario.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

albyhub_list_channelsA

List Lightning channels — typically peer pubkey, capacity, local/remote balance, public/private flag, online status. Hits GET /api/channels. The hub-wide view (vs. nwc-mcp which has no channel concept). Useful for spotting offline channels, low inbound, etc.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure. It explicitly mentions 'Hits GET /api/channels', indicating a read-only operation, and describes typical response fields. However, it omits details like pagination, error behavior, or authentication requirements, which would have made it more transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded with the core purpose and field list. However, it includes a tangential comparison to nwc-mcp and an implementation detail ('Hits GET /api/channels') that, while informative, add minor clutter and could be trimmed without losing essential meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple parameterless list tool without an output schema, the description adequately covers what the tool does, what it returns, and its diagnostic use cases. It lacks explicit mention of limits, sorting, or response structure, but these are not critical for such a straightforward tool, so it is sufficiently complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the schema coverage is trivially 100% and the baseline is 4. The description adds value by explaining what the returned data contains, which is the only relevant semantic here since there are no parameters to document.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists Lightning channels and enumerates typical fields (peer pubkey, capacity, local/remote balance, public/private flag, online status). It distinguishes from sibling tools like get_balances or get_node_info by focusing on channel-level data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides context for when to use the tool, such as spotting offline channels or low inbound liquidity. It also contrasts with nwc-mcp, but does not explicitly list sibling alternatives or exclusions, so it stops short of full when/when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

albyhub_proxy_requestA

Generic HTTP proxy to your Alby Hub admin API. Use this when no typed convenience tool exists for the endpoint you need. Returns the response status, headers, and (JSON-parsed when possible) body. Non-GET methods are gated by ALBYHUB_READ_ONLY and ALBYHUB_REQUIRE_CONFIRM. Pair with the Hub's own docs to discover endpoints; the typed wrappers (get_node_info, list_apps, get_balances) are layered on top of this and good defaults to start with.

ParametersJSON Schema
NameRequiredDescriptionDefault
bodyNoRequest body — passed as JSON if an object, raw if a string. Ignored for GET/HEAD/OPTIONS.
pathYesPath on the Hub, e.g. `/api/info` or `/api/channels`. Combined with ALBYHUB_URL.
queryNoQuery-string params (string → string).
methodYesHTTP method. GET/HEAD/OPTIONS are always allowed; others gated by READ_ONLY + REQUIRE_CONFIRM.
timeout_msNoRequest timeout in ms (default 15000, max 60000).
extra_headersNoExtra HTTP headers to merge in. Useful if your Hub expects `X-API-Key` instead of `Authorization: Bearer`.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of behavioral disclosure. It discloses the return format ('response status, headers, and (JSON-parsed when possible) body') and critical safety gating ('Non-GET methods are gated by ALBYHUB_READ_ONLY and ALBYHUB_REQUIRE_CONFIRM'). It does not cover error handling or rate limits, but the essential behavior is well communicated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is four sentences, each earning its place: purpose, usage guidance, return behavior, and relationship to siblings. It is front-loaded with the generic-purpose statement and contains no redundant phrases.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a generic proxy tool with no output schema and no annotations, the description covers the essentials: when to use it, what it returns, safety gating, and how to discover endpoints. It does not detail error cases or authentication setup, but those are less critical for a low-level catch-all proxy. Overall, it is sufficiently complete for its purpose.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

All six parameters have descriptions in the schema, so the baseline is 3. The description adds no additional parameter semantics beyond what the schema already provides—for example, the gating on non-GET methods is already stated in the method parameter description. Thus, the description neither compensates nor detracts.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Generic HTTP proxy to your Alby Hub admin API', clearly stating a specific verb (proxy) and resource. It also distinguishes itself from siblings by explicitly saying 'Use this when no typed convenience tool exists' and naming the typed wrappers (get_node_info, list_apps, get_balances) as alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides explicit when-to-use guidance: 'Use this when no typed convenience tool exists for the endpoint you need.' It also recommends the typed wrappers as good defaults, giving clear direction on choosing this tool versus alternatives.

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. 6 tool updatesv0.1.0
    • First observedalbyhub_confirm_request
    • First observedalbyhub_get_balances
    • First observedalbyhub_get_node_info
    • First observedalbyhub_list_apps
    • First observedalbyhub_list_channels
    • First observedalbyhub_proxy_request

TDQS

A4.7/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: generic proxy, confirmation step, and specific typed wrappers for node info, balances, apps, and channels. The proxy_request tool is explicitly a fallback for endpoints without a dedicated wrapper, so there is no confusion about when to use it.

Naming Consistency5/5

All tools share the consistent 'albyhub_' prefix and follow a verb_noun pattern (proxy_request, confirm_request, get_node_info, get_balances, list_apps, list_channels). The naming is uniform and predictable.

Tool Count5/5

With 6 tools, the set is well-scoped for an admin API wrapper. The generic proxy plus a few convenient typed wrappers cover the domain without redundancy or clutter.

Completeness5/5

The inclusion of a generic proxy_request tool ensures that any endpoint of the Alby Hub admin API can be accessed, so there are no dead ends. The typed wrappers cover common operations, and the proxy fills any gaps, making the surface complete.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    MCP server for l402-kit — enables AI agents (Claude, Cursor, etc.) to autonomously pay Bitcoin Lightning-protected APIs. Tools: l402_fetch, l402_balance, l402_spending_report. Run with: npx l402-kit-mcp
    4
    53 npm
    3
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Model Context Protocol (MCP) server for Polar Lightning that enables AI assistants to manage Bitcoin Lightning Network test environments, including network creation, node management, Bitcoin operations, Lightning channel management, and Taproot Assets.
    10 npm
    7
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    MCP server exposing a Lightning wallet to LLM agents over Nostr Wallet Connect (NIP-47): balance, invoices, LN address/LNURL payments, batch pay, and keysend. All spend tools are wrapped in a defense-in-depth safety stack — budget caps, allowlist, two-step confirmation, audit log.
    13
    26 npm
    MIT