@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.
Maintainers
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
- Open utm.castnexo.com.br and sign in
- Open the user menu, then API keys
- Click Create key, give it a name that says where it will run
- 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-builderClaude 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
