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

@editpink/mcp

v0.7.3

Published

Pink Editor MCP server — gives your AI client editorial framework + content graph + recall over your published content

Readme

@editpink/mcp — Pink Editor MCP server

Local stdio MCP server that gives your AI client (Claude Code, Claude Desktop, Cursor, Windsurf) the editorial framework + content graph + recall + publishing flow over your Pink-Editor-managed content.

AI client  ──stdio──►  editpink-mcp  ──HTTPS──►  app.edit.pink /api/cm/mcp/*  ──►  executor

Why: drive content work from the client you're already in, using your own Pro/Max subscription quota instead of paying API tokens — and have the host model adopt your editorial framework automatically on every session.

What it does

Three mechanisms converge on "playbook loaded" so the host model behaves like your editorial team, not generic Claude:

  1. /pink slash prompt — type /pink in any MCP client; the prompt server-side hydrates the editorial playbook + the current site's foundation (brand, audiences, goals, CTAs) + the list of available sites. First call loads everything; later calls in the same session are lightweight reminders.
  2. get_foundation tool — embeds the same playbook in its response, so models that skip /pink still learn the rules the moment they call it.
  3. Tool description breadcrumbslist_sitesset_siteget_foundation walks any first-time model through the bootstrap.

Install

Claude Code

Add to ~/.claude.json:

{
  "mcpServers": {
    "editpink": {
      "command": "npx",
      "args": ["-y", "@editpink/mcp"],
      "env": {
        "EDITPINK_API_URL": "https://app.edit.pink"
      }
    }
  }
}

Or, while developing against this repo, point at the local file:

{
  "mcpServers": {
    "editpink": {
      "command": "node",
      "args": ["/Users/dk/Desktop/main/edit.pink/editor/mcp-servers/pink/index.mjs"],
      "env": {
        "EDITPINK_API_URL": "http://localhost:3000"
      }
    }
  }
}

Then restart Claude Code. Tools appear as mcp__editpink__<tool> (e.g. mcp__editpink__list_sites). The /pink prompt appears in the slash menu.

Claude Desktop

Same JSON block goes in ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%/Claude/claude_desktop_config.json (Windows). Restart the app.

Cursor

Add to ~/.cursor/mcp.json (or the project-local .cursor/mcp.json) with the same shape.

Windsurf

Add to ~/.codeium/windsurf/mcp_config.json with the same shape.

Auth — first call triggers device flow

On the first tool call, the bridge runs the RFC 8628 device-authorization flow:

  1. Hits POST /api/mcp/device-code, gets a user_code + verification URL.
  2. Opens your default browser to the verification page (or prints the URL on stderr if no browser is available).
  3. You sign in to Pink Editor and approve the code.
  4. The bridge polls POST /api/mcp/device-code/poll until approved, then persists the issued token to ~/.editpink-mcp-state.json.
  5. Subsequent tool calls use that token; no re-auth until you revoke it.

You can skip the flow entirely by setting EDITPINK_API_KEY in the env block above to an admin API key — useful for headless / CI usage. The env var always wins over the on-disk token, and is never written to the state file.

First run

  1. /pink — loads playbook, foundation (if a site is already pinned), and the list of your sites.
  2. If no site is pinned, the prompt tells the model to call list_sites then set_site({site_id: <id>}). The pinned site survives across restarts.
  3. get_foundation — pulls the site's brand, audiences, goals, CTAs, playbook, writable_cols, skills/memory registries, today's date, and current selection in one call.

Tool surface

Everything below is exposed by the stdio bridge and dispatches to /api/cm/mcp/call (or a dedicated bridge route for the lifecycle tools).

Site lifecycle (bootstrap)

| Tool | What | |---|---| | list_sites | Every site you can read. Each row carries is_member and read_only. | | set_site({ site_id }) | Pin a site for the rest of the session. Returns the foundation immediately so you don't need a second call. | | get_site | The pinned site row only (light). | | get_foundation | Full foundation refresh — same shape set_site returned. | | get_selection | What the user has open in the Pink Editor UI right now (page/topic with keywords, pains, questions, notes pre-joined). Call before acting on "this" / "the current page". |

Reads & planning

| Tool | What | |---|---| | db_select | Site-scoped read of any allowed cm_* table. | | graph({ predicate }) | Dense CSV map of the content graph. Predicates: inventory, cannibals, orphans, stale, underlinked, missing_primary, coverage, intent_mix, neighbors. | | recall | Vector recall across the site's cm_chunks. Cheap (one embedding call); run before research. | | research | Serper SERP + URL scrape + LLM synthesis. Paid. | | fetch_keywords | Google Keyword Planner volume + CPC for a list of keywords (paid). | | query_stats | Stats summary across the site's plan. |

Writes (CRUD)

| Tool | What | |---|---| | db_insert | Insert into allowed cm_* tables. site_id auto-stamped. | | db_update | Patch existing rows by id (or composite PK). | | db_delete | Soft-delete on tables that support it; hard-delete elsewhere. | | apply_link_delta | Bulk-edit cm_page_links with a soft floor warning when deletes shrink the link count. | | merge_topics | Merges only — creates and renames go through db_insert / db_update. |

Publishing — the ONLY MCP path to take a page live

Works for every page_type — editorial (Article / Pillar / FAQ / Landing) and Utility (privacy / terms / about). The publish flow is uniform; Utility pages just use a smaller block subset and skip the AUDIENCE: line.

| Tool | What | |---|---| | get_article_brief({ page_id }) | Foundation + page + questions + research + recall + block vocab in one read. Free. | | save_article_copy({ page_id, payload }) | Phase 1 of 2. Write the article PROSE as plain markdown (first line AUDIENCE: <name>). Creates a draft content_articles row and vectorizes the prose. Page is NOT live yet. 1 credit. | | save_article_blocks({ page_id, body }) | Phase 2 of 2. Convert the prose to Block[] per publisher/schema/blocks.json. Server validates blocks, flips cm_pages.published = 1, AND pushes to the live site via the Pink Publish Protocol. 0 credits (paid in phase 1). | | generate_article({ page_id }) | Server-side alternative — Anthropic API runs the full pipeline. We pay the tokens. Pillars cascade through child pages (15–30+ min). | | get_pipeline_status({ page_id }) | Poll the server-side pipeline progress. Don't tight-loop in one turn — check on the user's next message. |

cm_pages.published and cm_questions.published are READ-ONLY through db_update — flipping them directly bypasses block validation and the live-site push (the reader never sees a "published" row that wasn't pushed). Use the two-phase flow above instead.

There is no MCP path to UNPUBLISH or move a page to DRAFT yet — flag to the user if asked.

GSC analytics (read-only)

| Tool | What | |---|---| | gsc_query_stats | Aggregated impressions / clicks / position per query, with filters. | | gsc_striking_distance | Queries ranking 8–20 — close to page-1 wins. | | gsc_content_decay | Pages losing clicks vs trailing 4-week baseline. | | gsc_cannibalization | Multiple URLs competing for the same query. | | gsc_hidden_winners | High-impression, low-CTR rows worth retitling. | | gsc_forecast | Projected clicks for a planned page. |

Skills, memory, recovery

| Tool | What | |---|---| | load_skill({ name }) | Pull a per-site editorial playbook on demand. Discovered via get_foundation. | | load_memory({ name }) | Pull a per-site memory blob. | | remember({ name, body }) | Persist future-conversation facts (not drafts/deliverables). | | undo({ scope: 'last_call' \| 'last_turn' }) | Roll back via the journal. No approval gate — every write commits and is journaled. |

Env vars

| Var | Default | Notes | |---|---|---| | EDITPINK_API_URL | http://localhost:3000 | Pink Editor backend origin. Use https://app.edit.pink in production. | | EDITPINK_API_KEY | — | Optional. If set, skips the device flow. Useful for headless / CI usage. |

State persists at ~/.editpink-mcp-state.json (pinned site_id + issued token) so you don't have to re-pick a site or re-auth every session.

Troubleshooting

  • Browser opened to a /device page asking for a code — that's the device flow on first call. Sign in to Pink Editor and approve the code shown on stderr.
  • Tool "X" failed: HTTP 401 — token revoked or EDITPINK_API_KEY mismatch. Delete ~/.editpink-mcp-state.json to re-trigger the device flow, or fix the env var.
  • Tool "X" failed: HTTP 404 cm_sites N not foundset_site pointed at a non-existent site. Run list_sites and pick a real id.
  • No current site — call set_site before invoking any site-scoped tool.
  • Connection refused — the backend at EDITPINK_API_URL isn't reachable.
  • State file corruption — delete ~/.editpink-mcp-state.json and let the device flow run again.