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

@plukio/mcp-server

v0.18.0

Published

MCP (Model Context Protocol) server that gives AI coding agents access to Pluk tasks. Pull tasks, update status, leave notes for reviewers — all from within Claude Code, Cursor, or any MCP-compatible client.

Readme

@plukio/mcp-server

MCP (Model Context Protocol) server that gives AI coding agents access to Pluk tasks. Pull tasks, update status, leave notes for reviewers — all from within Claude Code, Cursor, or any MCP-compatible client.

Important: one server per project

Pluk API keys are scoped to a single site. Each of your client sites has its own key, its own tasks, and its own context. This means:

  • Configure the MCP server locally in each project repo, not globally
  • Each project gets the API key for its corresponding Pluk site
  • Tasks, company defaults, and site context all come from the site tied to that key

This is by design — Pluk operates at the site level so your AI agent always has the right context for the project it's working in, without cross-site data leaking between repos.

Setup

1. Get your site's API key

Generate one from the Pluk dashboard under your site's settings. Keys start with pluk_.

2. Configure your MCP client

Always add this to the project directory (e.g. .mcp.json in the repo root), not to your global config. Each project needs its own Pluk connection tied to the correct site.

Claude Code

Add to your project's .mcp.json:

{
  "mcpServers": {
    "pluk": {
      "command": "npx",
      "args": ["-y", "-p", "@plukio/mcp-server", "plukio-mcp-server"],
      "env": {
        "PLUK_API_KEY": "pluk_your_key_here"
      }
    }
  }
}

Or via CLI (run from the project directory):

claude mcp add pluk -- npx -y -p @plukio/mcp-server plukio-mcp-server

Then set PLUK_API_KEY in the MCP config's env block.

Cursor / Other MCP clients

Point to the same command (npx -y -p @plukio/mcp-server plukio-mcp-server) with PLUK_API_KEY set in the environment. Configure it per-project, not globally.

Environment variables

| Variable | Required | Description | |---|---|---| | PLUK_API_KEY | Yes | Your site's Pluk API key (site-scoped) | | PLUK_API_URL | No | API base URL (defaults to https://pluk.io) |

Tools

pluk_list_tasks

List tasks with optional filters. Returns lightweight summaries sorted by priority (expedited first, then standard, in Kanban board order). Only backlog tasks are returned by default.

| Parameter | Type | Description | |---|---|---| | type | string | Filter by type: code, content, design, support | | status | string | Comma-separated: backlog, on_deck, in_progress, needs_review, done | | intent | string | expedited or standard | | priority | string | normal or focus | | zone | string | Strict positive filter on repo area — only tasks tagged with exactly this zone match; untagged tasks are excluded | | exclude_zones | string[] | Skip tasks in these zones (max 64). Untagged tasks stay eligible — a null zone means nobody derived one yet, not "safe to skip" | | limit | number | Max results (default 5, max 100) | | offset | number | Skip N tasks for pagination |

Each returned task carries zone (string or null) — the repo-area id it was last tagged with, e.g. web-dashboard. Zone ids come from a repo's committed .plukit-zones.json, and the stored value is a cache, never truth: a Pluk site can front more than one repo, and repos restructure. Re-validate a zone against your own zone file and ignore ids you don't recognise.

pluk_claim_next_task

Atomically claim the next task for this coder and get it back already marked in_progress and owned by you, or { task: null }. Runs the whole pickup waterfall server-side — prefer it over pluk_list_tasks for picking up work.

| Parameter | Type | Required | Description | |---|---|---|---| | coder_id | string | Yes | Stable per-folder coder identity (e.g. contents of ./.plukit/id) | | type | string | No | Task type slug to claim (default: any). Use code in coding sessions. | | zone | string | No | Strict positive filter on repo area — only tasks tagged with exactly this zone are claimable; untagged tasks are excluded | | exclude_zones | string[] | No | Skip tasks in these zones (max 64) — the common path, for avoiding areas another live worker holds. Untagged tasks stay claimable. | | site_id | string | No | Site UUID to claim from. Only needed when the key spans multiple sites. |

Zone filters are applied inside the atomic claim, so a worker steering away from a busy area never races between peeking and claiming. The claimed task carries zone — re-validate it against your .plukit-zones.json before trusting it.

pluk_get_task

Get full task details by ID, including description, custom fields, site info, company defaults, and testing findings (review feedback). The response includes zone (string or null) — the repo-area id the task was last tagged with, a per-repo cache to re-validate rather than trust.

| Parameter | Type | Required | Description | |---|---|---|---| | task_id | string | Yes | Task UUID |

pluk_update_task

Update a task's status, title, or notes.

| Parameter | Type | Required | Description | |---|---|---|---| | task_id | string | Yes | Task UUID | | title | string | No | Updated title (use to prepend "NEED INFO - ") | | status | string | No | backlog, on_deck, in_progress, needs_review, done, blocked | | ai_coder_notes | string | No | ELI5 summary for the reviewer. Required when setting needs_review. |

pluk_get_company

Get company context: tech stack, repo URL, staging URL, and active sites.

| Parameter | Type | Required | Description | |---|---|---|---| | company_id | string | Yes | Company UUID (from a task's organization field) |

pluk_whoami

Diagnostic health check. Takes no parameters. Confirms which API key, organization, and site the server authenticated as — run it first whenever tools return 401 or seem to be hitting the wrong org.

Returns:

{
  "authenticated": true,
  "organization": "s2s Communications",
  "organization_id": "…",
  "site": { "id": "…", "name": "…" },
  "scopes": ["tasks:read", "tasks:write"],
  "key_fingerprint": "a1b2"
}

key_fingerprint is the last 4 characters of the key actually in use — compare it against the key in your config to confirm the server booted with the right one. A 401 here (rather than a result) means the key is missing or rejected; the error body includes key_status (key_missing vs key_rejected) and the fingerprint the server saw.

Rotating your API key

Rotating a key is not just a config edit — a stale server process or the Claude Code config cache can keep the old key alive. If tools 401 after a rotation even though the new key works via curl, follow this exactly:

  1. Rotate the key in the Pluk dashboard and copy the new one.
  2. Update PLUK_API_KEY in both places — your project's .mcp.json and the cached copy in ~/.claude.json (this cache overrides .mcp.json, so updating only one leaves the old key in play).
  3. Verify the new key works:
    curl -H "X-Pluk-API-Key: <NEW_KEY>" https://pluk.io/api/mcp/whoami
  4. Kill orphaned server processes — a plain restart may reconnect to one still holding the revoked key:
    pkill -f "@plukio/mcp-server"
  5. Restart your MCP client (Claude Code) to spawn a fresh server.
  6. Run pluk_whoami and confirm key_fingerprint matches your new key and the org is correct.

Workflow

pluk_list_tasks (limit=1)     → Get next task
pluk_get_task (task_id)       → Read full details
pluk_update_task (in_progress) → Mark as started
  ... do the work ...
pluk_update_task (needs_review, ai_coder_notes) → Submit for review

If a task lacks enough detail to start:

pluk_update_task (title="NEED INFO - ...", status=on_deck)

Development

# Build
pnpm build

# Watch mode
pnpm dev

# Test locally with Claude Code (point .mcp.json at local build)
# "args": ["./packages/mcp-server/dist/index.js"]

License

Private — Pluk.io