Skip to main content
Glama

rss-mcp - Superduper local-first RSS reader + readability extractor

CI FastMCP Python 3.13 License: MIT

Subscribe to feeds, get clean article text without ad sites, full-text + semantic search. Pure local SQLite, no account needed.

Features & Preview

  • Dashboard: High-level KPIs (feeds, total items, unread, starred).

  • 3-Pane Reader: Feeds navigation, articles stream, and clean readability text extract pane.

  • Feeds Manager: OPML import/export, feed health audits, refresh triggers.

  • Inbox & Starred: Unified triage inbox and starred bookmarks.

  • RAG & Search: FTS5 SQLite full-text search combined with LanceDB semantic vector sweeps.

  • Chat & LLM: Built-in LLM exploration assistant with dynamic provider detection (Ollama, LM Studio, etc.).

Related MCP server: Local RAG

Framework Stack

  • Backend: FastMCP 3.1+, Starlette / Uvicorn, SQLite3 WAL + FTS5, Trafilatura, LanceDB, Pyright (zero errors).

  • Frontend: React 19, TypeScript, Vite, Tailwind CSS, Zustand, Lucide React, Biome linter.

Install & Run

Option

Command

A naked PC

pwsh -File start.ps1 (installs uv/bun via winget as needed)

B dev backend

uv sync ; uv run python -m rss_mcp --serve

C stdio (Claude Desktop)

uv run python -m rss_mcp

D frontend

cd webapp ; bun install ; bun run dev --port 11975

See INSTALL.md. Onboarding: N/A (pure local util, no wrappee/account) - rationale in docs/DEVELOPMENT.md.

Claude Desktop Configuration

Add to your claude_desktop_config.json:

{
  "mcpServers": {
    "rss-mcp": {
      "command": "uv",
      "args": [
        "--directory",
        "d:/Dev/repos/rss-mcp",
        "run",
        "python",
        "-m",
        "rss_mcp"
      ]
    }
  }
}

Environment Variables

Variable

Default

Description

RSS_MCP_PORT

11974

Backend server port (strict fleet standard)

RSS_MCP_WEBAPP_PORT

11975

Webapp frontend port

RSS_MCP_HOST

127.0.0.1

Host address to bind to

RSS_MCP_DB

data/rss.sqlite3

SQLite database file path

RSS_MCP_LANCE_PATH

data/lancedb

LanceDB vector database directory

Tools (all real, no stubs)

  • feeds_ops: subscribe, unsubscribe, list_feeds, refresh_feed, refresh_all, fetch_items, get_item, mark_read, mark_star, remove_item, opml_import, opml_export, feed_health

  • readability_ops: extract, get_cached, clear_cache, list_extractors

  • reader_ops: inbox, starred, search_text, search_semantic, stats, trigger_sweep, sweep_status

  • show_reader_prefab_card: Prefab card view for visual readers

  • rss_help: Interactive help and quickstart

  • rss_shutdown: Clean server termination

Ports

Backend 11974, frontend 11975. Forbidden ports are never used (3000, 5000, 5173, 8000, 8080).

vs glance-mcp

glance-mcp is a lightweight holdall (single-shot fetch, weather, probes). rss-mcp is the stateful full reader: subscriptions, polling with ETag, readability cache, FTS5, stars, OPML, background sweeps.

Development

  • Justfile shortcuts: just lint, just typecheck, just test, just ci, just gates-green

  • Biome check: bun run biome:ci (in webapp/)

  • Pre-commit hook: powershell.exe -NoProfile -File scripts/pre-commit-biome.ps1

  • Pack MCPB bundle: powershell.exe -NoProfile -File scripts/mcpb-pack.ps1

Available Tools

6 tools
feeds_opsB

feeds_ops - Full feed subscription lifecycle.

RATIONALE: groups subscribe/unsubscribe/list/refresh/fetch/get/mark/star/remove/opml/health into one discoverable tool. Stateful reader, unlike glance-mcp single-shot fetch.

Return Format

Dictionary with success (bool), message (str), and operation-specific payload (e.g. feeds, items, feed, opml).

Examples

  • {"operation": "list_feeds"} -> lists all subscribed feeds.

  • {"operation": "subscribe", "url": "https://news.ycombinator.com/rss"} -> subscribes to RSS feed.

  • {"operation": "refresh_all"} -> polls all feeds for new articles.

  • {"operation": "fetch_items", "limit": 20, "unread_only": true} -> retrieves unread articles.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlNo
limitNo
titleNo
feed_idNo
is_readNo
item_idNo
operationYesFeed operation to run
opml_textNo
is_starredNo
unread_onlyNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior3/5

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

With no annotations, the description carries the full burden but only partially meets it: it discloses that the tool is stateful (vs single-shot fetch) and that responses follow a success/message/payload shape. It says nothing about the destructive semantics of unsubscribe/remove_item, permission or auth requirements, or rate limits on refresh_all.

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?

Front-loaded with the purpose, then clearly sectioned into rationale, return format, and examples. The rationale section is somewhat self-referential meta-commentary, but overall the structure is tight and every example earns its place.

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

Completeness3/5

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

An output schema exists, so the return-format section is arguably redundant, and the real gap is the undocumented parameters and unstated side effects for the mutating operations. For a 10-parameter, 13-operation mega-tool with zero annotations, the description is only minimally sufficient.

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

Parameters2/5

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

Schema coverage is only 10% across 10 parameters, so the description is expected to compensate heavily. The examples clarify operation, url, limit, and unread_only, but feed_id, item_id, is_read, is_starred, opml_text, and title are left entirely undocumented in both schema and prose.

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

Purpose4/5

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

States the resource (feed subscriptions) and enumerates the full operation set — subscribe/unsubscribe/list/refresh/fetch/get/mark/star/remove/opml/health — which tells an agent exactly what surface this tool covers. It does not, however, differentiate itself from the actual siblings (reader_ops, readability_ops); its only comparison is to 'glance-mcp,' which is not in the sibling list.

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

Usage Guidelines3/5

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

The four examples imply usage for a handful of operations, and the rationale explains why the operations are consolidated into one tool. There is no explicit when-to-use / when-not-to-use guidance relative to reader_ops or readability_ops, so an agent must infer from the operation names alone.

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

readability_opsA

readability_ops - Clean article text without ad sites.

RATIONALE: trafilatura primary plus readability-lxml fallback, cached in SQLite. No paywall bypass: if the page needs login, extraction reports failure honestly.

Return Format

Dictionary with success (bool), message (str), and article text fields (title, author, text, html, extractor, cached).

Examples

  • {"operation": "extract", "item_id": 3} -> downloads article and extracts cleaned text.

  • {"operation": "get_cached", "item_id": 3} -> retrieves previously cached clean extraction.

  • {"operation": "list_extractors"} -> lists available readability engines.

ParametersJSON Schema
NameRequiredDescriptionDefault
forceNo
item_idNo
operationYesReadability operation to run

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/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 and does meaningful work: it discloses SQLite caching, the primary/fallback extractor chain, and honest failure reporting when a login/paywall is encountered. It still omits permission or rate-limit behavior, and the 'clear_cache' operation's destructive effect on stored extractions is never described.

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 front-loaded with the purpose, then uses clear headers for rationale, return format, and examples. The RATIONALE is arguably internal-implementation detail, but it is short and earns its place by explaining the caching and fallback semantics.

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

Completeness3/5

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

An output schema exists, so the Return Format block is somewhat redundant but harmless. The gaps are on the input side: one of four enum operations ('clear_cache') and one of three parameters ('force') go undocumented, which leaves an agent unable to safely invoke those paths.

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?

Schema coverage is only 33%: 'operation' is documented and enum-bound, but 'item_id' and 'force' have no schema descriptions. The examples add meaning to item_id (an article id) but 'force' is never explained in either place, and 'clear_cache' appears in the enum without any clarifying example.

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

Purpose4/5

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

The description states a specific verb and resource — 'Clean article text' — plus a 'RATIONALE' naming trafilatura with a readability-lxml fallback, so the agent knows exactly what the tool produces. It does not, however, differentiate itself from the sibling reader_ops, which risks confusion between two reading/extraction tools.

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

Usage Guidelines3/5

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

The Examples section implicitly shows when to use each operation (extract for a fresh download, get_cached for a prior extraction), which is better than nothing. But there is no explicit statement of when to prefer this tool over reader_ops, nor any when-not guidance beyond the 'no paywall bypass' remark.

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

reader_opsA

reader_ops - Daily reading surface: inbox, stars, search, stats, RAG sweeps.

RATIONALE: single entry point for what a human checks every morning.

Return Format

{success, message, items/stats/job/job_id/status/chunks}

Examples

  • {"operation": "inbox"} unread items

  • {"operation": "search_text", "query": "vienna"} FTS search

  • {"operation": "search_semantic", "query": "rocket engine"} vector search

  • {"operation": "trigger_sweep", "mode": "incremental", "hours": 4} background index job

ParametersJSON Schema
NameRequiredDescriptionDefault
ctxNo
modeNoSweep mode: incremental or full. Used by: trigger_sweepincremental
hoursNoLookback hours for incremental sweep. Used by: trigger_sweep
limitNo
queryNo
job_idNo
feed_idNoScope sweep to one feed id, 0 means all. Used by: trigger_sweep
operationYesReader operation to run

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior3/5

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

With no annotations at all, the description carries the full behavioral burden. It does disclose something valuable: trigger_sweep creates a background job (job/job_id/status in the return shape), implying async behavior the caller must poll. It says nothing about permissions, cost, or what a sweep mutates.

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?

Front-loads the purpose, then return format, then concrete request examples — a sensible structure for a dispatch tool. The RATIONALE line and the return-format block are somewhat redundant given an output schema exists, but nothing is badly bloated.

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 multiplexed tool the key requirement is mapping operations to payloads, and it gives that. The returns are covered by an output schema...

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?

Schema coverage is 50%, and the schema itself already tags mode/hours/feed_id with "Used by: trigger_sweep." The examples add a useful param-to-operation mapping (query paired with search_text/search_semantic, mode/hours with trigger_sweep), but limit, job_id, and ctx remain undocumented anywhere. Marginal value over the schema.

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

Purpose4/5

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

The description names the resource (reading surface) and enumerates the concrete operations it multiplexes: inbox, stars, search, stats, RAG sweeps. It is clearly a single dispatch entry point rather than a tautology. It stops short of distinguishing itself from siblings like feeds_ops or readability_ops, so an agent must infer the boundary.

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

Usage Guidelines3/5

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

"Single entry point for what a human checks every morning" implies a daily-triage usage context, which is genuine guidance. However, it never states when to prefer feeds_ops/readability_ops, nor any exclusions or prerequisites (e.g., when a sweep is appropriate vs. an index query). Usage is implied, not prescribed.

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

rss_helpB

rss_help - Capability summary and op list.

Return Format

Dictionary with success (bool), message (str), registered tools, ports, and comparison vs glance-mcp.

Examples

  • {} -> summary of reader capabilities and registered tools.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior3/5

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

With no annotations, the description carries the full burden, and it does disclose the return shape (success bool, message, registered tools, ports, comparison vs glance-mcp). However it says nothing about side effects or that this is a safe, read-only introspection call, and the return detail overlaps the existing output schema.

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?

Front-loaded with a one-line purpose, then headers for Return Format and Examples. The sections are short, though the Return Format block largely restates what the output schema already provides.

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 no-arg introspection tool with an existing output schema, the definition is essentially complete: it names the purpose and shows the call. It could be fuller only by stating when to prefer it over the ops siblings.

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 takes zero parameters, so there is nothing for the description to disambiguate beyond confirming the empty-object call. Baseline 4 applies for a no-parameter tool.

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

Purpose4/5

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

States a specific purpose: a capability summary and operation list for the rss/reader toolset. The verb+resource is clear (help/introspection), though it does not differentiate itself against siblings like feeds_ops or reader_ops by explaining what those siblings do instead.

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

Usage Guidelines2/5

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

There is no guidance on when to call this tool versus the sibling ops tools, nor any statement of prerequisites or exclusions. The example shows the trivial call signature but not the situation that should trigger it.

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

rss_shutdownA

rss_shutdown - Graceful shutdown hook for the daemon.

Return Format

Dictionary with success (bool) and acknowledgement message (str).

Examples

  • {} -> acknowledges shutdown request.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.5/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full behavioral burden. It does add useful nuance beyond the name by calling the shutdown 'graceful' and by noting the response is an acknowledgement of a 'request', hinting that termination may be asynchronous rather than immediate. However, it never states what actually gets stopped, whether in-flight work is drained, whether the daemon process exits, or what authority is required to trigger it.

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 definition is short and front-loads the purpose in the first line, then adds return format and a one-line example. The markdown section headers are slightly heavy for a zero-parameter tool whose return shape is already covered by the output schema, but nothing is padded or redundant in a harmful way.

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

Completeness3/5

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

With an output schema present, the description need not explain the return value, yet it does so anyway, so no gap exists there. The remaining ambiguity is functional: it does not resolve whether this actually shuts down the daemon or merely registers/acknowledges a shutdown hook, which matters for an operationally significant, irreversible-feeling call with no annotations to fall back on.

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 takes zero parameters (empty object, additionalProperties: false), so there is nothing to document and the baseline of 4 applies. The description correctly shows the empty invocation as '{}' in its example, reinforcing that no arguments are accepted.

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

Purpose4/5

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

The description names a specific verb and target ('Graceful shutdown hook for the daemon'), so an agent immediately knows this terminates/stops the daemon rather than performing any RSS feed work. Sibling tools (feeds_ops, readability_ops, reader_ops) are unrelated operation groups, so no differentiation is required, but nothing beyond the name is added to sharpen the scope.

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

Usage Guidelines3/5

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

Usage is only implied by 'shutdown hook for the daemon' — an agent can infer this is called when the daemon should stop, but there is no explicit statement of when to call it versus letting the process exit naturally, nor any prerequisites or warnings. The word 'hook' suggests it may be invoked by a host process rather than by an agent, which is left unclarified.

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

show_reader_prefab_cardB

show_reader_prefab_card - Prefab stats card for list/status/stats coverage.

Return Format

ToolResult with PrefabApp structured content plus plain-text fallback.

Examples

  • {} -> renders reader stats card.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.1/5.0
Behavior3/5

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

No annotations are present, so the description carries the full burden. It does disclose the return shape ('ToolResult with PrefabApp structured content plus plain-text fallback'), which is genuinely useful behavioral context, but it says nothing about whether rendering has side effects, permissions required, or whether the output is static vs. live data.

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 short and uses clear section headers for Return Format and Examples. It wastes a line restating the tool name verbatim ('show_reader_prefab_card - ...'), but otherwise every sentence carries information.

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

Completeness3/5

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

With no output schema, the description's Return Format section compensates adequately by naming ToolResult and the PrefabApp structured content. However, for a tool with no parameters and no annotations, the description never explains the card's purpose beyond 'stats', leaving the agent without a clear mental model of the rendered content.

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 takes zero parameters and the schema confirms this with additionalProperties: false, so there is nothing for the description to document. Baseline 4 applies for a parameterless tool.

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

Purpose3/5

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

The description names the resource ('reader prefab card') and frames it as a stats card for 'list/status/stats coverage', which hints at its role as a renderable summary view. However, 'Prefab stats card' is jargon and the verb 'show' conveys little about what the card actually contains or when it appears, and it does nothing to distinguish itself from sibling tools like reader_ops.

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

Usage Guidelines2/5

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

There is no guidance on when to invoke this tool versus reader_ops or the other reader-related siblings. The single empty-object example ('{} -> renders reader stats card') implies it takes no input but gives no conditions under which an agent should prefer it over 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 observedfeeds_ops
    • First observedreadability_ops
    • First observedreader_ops
    • First observedrss_help
    • First observedrss_shutdown
    • First observedshow_reader_prefab_card

TDQS

A3.5/5.0

Scored across 6 tools

Disambiguation3/5

feeds_ops and reader_ops both handle item retrieval and marking (e.g., fetch_items vs. inbox, mark/star in feeds_ops vs. stars in reader_ops), creating overlap that could cause misselection. show_reader_prefab_card also overlaps with reader_ops stats. Descriptions clarify intended separation, but boundaries are not crisp.

Naming Consistency3/5

Most tools use a consistent noun_ops pattern (feeds_ops, readability_ops, reader_ops), but rss_help and rss_shutdown use a different prefix, and show_reader_prefab_card uses a verb_noun format. The mix is readable but not predictable.

Tool Count5/5

Six tools is well-scoped for an RSS reader daemon. Each tool has a clear role: feed lifecycle, extraction, reading surface, help, shutdown, and a presentation card. None feels redundant or excessive.

Completeness5/5

The surface covers the full RSS reader lifecycle: subscription management (subscribe/unsubscribe/list/refresh/remove/OPML/health), article extraction and caching, reading inbox/stars/search/stats, background RAG sweeps, help, and graceful shutdown. No obvious operational gaps remain.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables intelligent RSS feed management with AI-powered semantic search, advanced filtering, and a comprehensive reading workflow. Supports OPML parsing, article organization with status tracking, and token-efficient browsing of large feed collections.
    15 npm
    5
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Privacy-first local document search using semantic search. Runs entirely on your machine with no cloud services, supporting PDF, DOCX, TXT, and Markdown files.
    22
    9
    3,151 npm
    390
    MIT