npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kivimedia/kmhub

v2.11.0

Published

KM Hub Terminal Mode. Installs the KM Hub MCP connector into your own Claude Code on your own machine, and ships the kmhub CLI that registers, updates and diagnoses it.

Readme

kmhub-mcp

A standalone MCP server for KM Hub. It exposes your workspace to any MCP client (Claude Desktop, Claude Code, IDEs, agents) using a KM Hub API key, by wrapping the public REST API (kmhub-api).

It ships in two transports that share the exact same tool set (tools.mjs plus the family modules in tools/):

  • Local stdio (index.mjs) - the client spawns the process; the org key comes from the KMHUB_API_KEY env var. One process = one workspace. Best for a single power user on their own machine.
  • Remote Streamable HTTP (remote.mjs) - one long-running server (hosted on the VPS) serves many orgs with zero local install. Each request authenticates with its own KM Hub key sent as a Authorization: Bearer kmh_live_... header, and is scoped to that org only. Deploy runbook: DEPLOY-VPS.md.

Tools

Tools are grouped into families, one file per family in tools/. tools.mjs discovers them at load time, so a new family is a new file and nothing else.

core - orientation and the CRM essentials

  • km_me - the connected workspace (id, name, plan) + the key's scopes
  • km_waiting - what needs you (approvals, enquiries, tasks, invoices, contracts)
  • km_list_clients - recent clients / leads (optional limit)
  • km_create_lead - create a lead (first_name, last_name, company, email, phone, notes)
  • km_list_deals - pipeline deals (optional limit, stage, status)
  • km_list_events - calendar events (optional limit, from/to start-date range)
  • km_list_bookings - recent bookings (optional limit, status, from/to event-date range)
  • km_create_inquiry - log an enquiry + its client (client_name required; event_type, event_date, budget_cents, notes, ...). Opens a pipeline deal automatically. Audited + undoable in the AI activity log.
  • km_create_booking - create a real booking + its client (client_name and event_date required; optional status: pending default or confirmed). Opens a pipeline deal at booked/won. Audited + undoable.
  • km_create_outreach_draft - queue an outreach message as a DRAFT (body required; optional subject, channel email/linkedin/ig/sms_whatsapp, deal_id, contact_id). It only QUEUES: a human approves the draft in the Approval Queue before anything can send. Audited.

meta - keeping the connection current

  • km_check_updates - asks KM Hub what it publishes today (GET /version returns api_version, rules_version, tools_version, min_client, changelog_url) and answers in plain language. Two judgements: is this connector still above min_client (the build KM Hub refuses to serve below), and is the rules file on disk still the published rules_version? Pass the local one in as rules_version. The rules pack carries a content hash after a +, and the two endpoints do not always both publish it, so the semver base and the hash are judged separately rather than looping on a suffix that proves nothing.
  • km_fetch_rules - downloads the current KM Hub operating rules (GET /rules) and returns { version, markdown, sha256, bytes, instructions }. The model is instructed to write that markdown verbatim over the user's global rules file (for Claude Code, their CLAUDE.md), replacing any older KM Hub block, and then to tell the user it did so.

Both meta tools degrade gracefully: if your KM Hub has not shipped /version or /rules yet they say "your KM Hub does not support update checks yet" and report success, rather than failing. The checksum is computed locally from the bytes that actually arrived; if KM Hub also sends one and the two differ, the response carries a warning instead of a silent bad write.

Profiles

Every tool schema is loaded into every turn, so a big tool set is a real context tax. A profile loads only the families you want:

| Profile | Loads | |---|---| | core | orientation + CRM essentials, plus meta | | outreach | core + the outreach families | | money | core + the billing families | | content | core + the content families | | coach | Fully Booked Coach operations, client delivery, acquisition, and content requests | | full | everything (default) |

full is the default, so nothing changes for an existing connection. An unknown profile name falls back to full rather than erroring: a typo in a config file should never cost someone their tools.

  • Remote: per request, POST /mcp?profile=money or an X-KMHub-Profile: money header. The query string wins if both are present. The profile is read from the request and passed down by argument, so the server stays stateless and two tenants can hold two different profiles at the same moment.
  • Local stdio: the KMHUB_PROFILE env var.

GET /health reports the families that loaded and the tool count for each profile.

Setup - local stdio (index.mjs)

  1. In KM Hub: Settings > Developer & API -> create an API key (kmh_live_...). Read tools need the read scope, create tools need write (a read-only key gets 403 on writes).

  2. Install deps in this folder:

    npm install
  3. Add to your MCP client.

    Claude Code (one command):

    claude mcp add kmhub -e KMHUB_API_KEY=kmh_live_xxxxxxxx -- node /absolute/path/to/kmhub/mcp-server/index.mjs

    Claude Desktop claude_desktop_config.json:

    {
      "mcpServers": {
        "kmhub": {
          "command": "node",
          "args": ["/absolute/path/to/kmhub/mcp-server/index.mjs"],
          "env": { "KMHUB_API_KEY": "kmh_live_xxxxxxxx", "KMHUB_PROFILE": "full" }
        }
      }
    }

    (Override the API base with KMHUB_API_BASE if self-hosting. KMHUB_PROFILE is optional and defaults to full.)

Setup - remote Streamable HTTP (remote.mjs)

No local install for the user - they point their client at the hosted VPS endpoint and authenticate with their own KM Hub key as a header. One server process serves every org; each request is scoped to the token it carries. Operators: see DEPLOY-VPS.md (pm2 kmhub-mcp, port 8830, https://mcp.kivimedia.co/mcp).

Claude Code (one command):

claude mcp add --transport http kmhub https://mcp.kivimedia.co/mcp \
  --header "Authorization: Bearer kmh_live_xxxxxxxx"

Add ?profile=core to the URL to load a smaller tool set:

claude mcp add --transport http kmhub "https://mcp.kivimedia.co/mcp?profile=core" \
  --header "Authorization: Bearer kmh_live_xxxxxxxx"

Claude Desktop / config-file clients:

{
  "mcpServers": {
    "kmhub": {
      "type": "streamable-http",
      "url": "https://mcp.kivimedia.co/mcp",
      "headers": {
        "Authorization": "Bearer kmh_live_xxxxxxxx",
        "X-KMHub-Profile": "full"
      }
    }
  }
}

Health check (no auth): GET https://mcp.kivimedia.co/health.

Adding tools

See tools/README.md for the family contract. Short version: drop a new tools/<family>.mjs exporting FAMILY, TOOLS, register(server, call, helpers) and an optional PROFILES, and it loads itself. You never edit tools.mjs, so parallel work on different families cannot collide. A family that fails to load, or claims a tool name another family already took, is skipped with a warning on stderr; the rest of the server carries on.

Notes

This is the same org-scoped, key-authed substrate the Telegram bot and Zapier use - one auth surface for all machine access. Everything is scoped to the key's workspace; a key can never reach another tenant's data. The API rate-limits each key to 60 reads and 20 writes per minute (429 + retry-after beyond that). Writes land in the AI activity log; outreach drafts additionally wait for human approval in the Approval Queue before any send.

Lapsed subscription (402). If the API answers 402 subscription_inactive, every tool in every family returns a plain-English message instead of a raw JSON blob: the subscription is not active, nothing in the workspace changed, and here is where to restart it. That is handled once in the shared out() helper in tools.mjs, so it covers families that do not exist yet. Other statuses keep the raw JSON body, which is what the model needs to reason about validation errors.