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

@castnexo/mcp-utm-builder

v0.1.1

Published

MCP server for Castnexo UTM Builder: create and organize UTM links, short links, clients and campaigns from an AI agent.

Readme

@castnexo/mcp-utm-builder

MCP server for Castnexo UTM Builder. It lets an AI assistant create and organize your tracked links, short links, clients and campaigns.

Instead of opening the app and filling the form once per link, you describe what you need and the assistant builds the links with consistent naming. That last part is the reason this exists: reports break when the same source shows up as Instagram, instagram and instagram, and naming by hand is where that drift comes from.

Requirements

  • Node.js 18 or newer
  • A Castnexo account with UTM Builder enabled
  • An API key, created in the app

Getting a key

  1. Open utm.castnexo.com.br and sign in
  2. Open the user menu, then API keys
  3. Click Create key, give it a name that says where it will run
  4. Copy the key right away. It is shown once and never again

Keys are valid for 90 days and can be renewed from the same screen. You can hold up to 10 active keys, and you can revoke any of them, or all at once, whenever you want.

Setup

Claude Code

claude mcp add utm-builder \
  --env CASTNEXO_API_KEY=cnx_live_your_key_here \
  -- npx -y @castnexo/mcp-utm-builder

Claude Desktop, Cursor, and other MCP clients

Add this to your MCP configuration file:

{
  "mcpServers": {
    "utm-builder": {
      "command": "npx",
      "args": ["-y", "@castnexo/mcp-utm-builder"],
      "env": {
        "CASTNEXO_API_KEY": "cnx_live_your_key_here"
      }
    }
  }
}

Restart the client afterwards so it picks up the new server.

Tools

| Tool | What it does | |---|---| | list_clients | Lists your clients | | list_campaigns | Lists campaigns, optionally filtered by client | | list_links | Lists saved links, optionally filtered by campaign or kind | | get_stats | Shows click counts for a link or a campaign | | create_client | Creates a client | | create_campaign | Creates a campaign inside a client | | create_utm_link | Creates a tracked link with UTM parameters | | create_short_link | Creates a short link with no UTM parameters | | update_link | Replaces an existing UTM link, keeping the same short code | | update_short_link | Updates a short link, changing only the fields you pass |

Things worth knowing

UTM values are normalized. Black Friday is saved as black-friday, and Promoção as promocao. Accents come off, spaces become hyphens, and everything is lowercased, so one source stays one row in your reports.

Ad platform macros are left alone. Anything containing { or }, such as {{campaign.name}} or {keyword}, is stored exactly as you wrote it. Those are literals the ad platform substitutes at click time, and lowercasing them would break the substitution.

update_link REPLACES a link, it does not patch it. Any UTM field you leave out is cleared, and leaving out campaign_id unfiles the link from its campaign. Ask the assistant to list the link first and send every field back, changing only what should change. Links carrying custom query parameters that are not UTMs should be edited in the web app, because those cannot be preserved through this tool.

That same tool changes a link that may already be published. The short code stays the same, so anyone who already has the old link will land on the new destination. That is the point of the tool, and also the reason to be deliberate with it.

Short links are updated with update_short_link, which behaves the opposite way. It patches: anything you leave out stays as it is. Use it for short links, and update_link for UTM links.

Listings are capped. Every list tool returns 50 results by default, 200 at most, and says so when it cuts (Showing 50 of 120 results.). Raise it with limit, or narrow the filters. get_stats with neither link_id nor campaign_id covers every link in the account, so pass a filter once the account grows.

What this server cannot do

Nothing here deletes. There is no tool to remove a client, a campaign or a link, and the API refuses those operations for API keys even if something tries to call them directly. Deleting is done by you, in the web app.

Key management is the same: a key cannot create, list or revoke another key. That only happens in a signed-in browser session, so a leaked key cannot make itself permanent.

Configuration

| Variable | Required | Default | |---|---|---| | CASTNEXO_API_KEY | yes | none | | CASTNEXO_API_URL | no | https://api.castnexo.com.br |

If something stops working

| Message | What to do | |---|---| | Key was not accepted | Check CASTNEXO_API_KEY, or create a new key in the app | | Key expired | Renew it under Settings, API keys. The same key keeps working after renewal | | Key was revoked | Create a new one. Revoked keys do not come back | | Operation not available to API keys | Do it in the web app. Deleting and key management are session only | | Too many requests | Wait a moment. Limits are per key |

Security

Treat the key like a password. Store it in your MCP client configuration or a password manager, never in a repository. If you think a key leaked, revoke it in the app and create another. Revoking takes effect on the next request.

This server sends the key only to the Castnexo API, over HTTPS, and never writes it to output.

License

MIT