{"_id":"@castnexo/mcp-utm-builder","_rev":"2-1269ace8d9aa83c317d3befe7877abf0","name":"@castnexo/mcp-utm-builder","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@castnexo/mcp-utm-builder","version":"0.1.0","keywords":["mcp","model-context-protocol","utm","utm-builder","short-links","marketing","castnexo"],"license":"MIT","_id":"@castnexo/mcp-utm-builder@0.1.0","maintainers":[{"name":"vcastilho","email":"contato@castnexo.com.br"}],"homepage":"https://utm.castnexo.com.br","bugs":{"url":"https://github.com/Castnexo/mcp-utm-builder/issues"},"bin":{"mcp-utm-builder":"dist/index.js"},"dist":{"shasum":"94d3c5620e31c4e8664be4717255cc2edec624a4","tarball":"https://registry.npmjs.org/@castnexo/mcp-utm-builder/-/mcp-utm-builder-0.1.0.tgz","fileCount":4,"integrity":"sha512-ueGK+zXHXRQbKMU+56JZfADp4nCpd5czwyvXl2xdhvksduCUC2U13X+3Qsx3H96tIB8qD462b9WmYMg9aDkiTw==","signatures":[{"sig":"MEQCIC3ZgDR5cFUWa8U1cg/CH939Ue1OZiWsATsBm4rMGirXAiAQOZY8YeKAL5eBOOcMwxLddGTewpQrjvRUm0+BB4oiqg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":20845},"main":"dist/index.js","type":"module","engines":{"node":">=18"},"gitHead":"7325c59f6c08fe2ab35f681f8d955f6d1f36318f","scripts":{"test":"npm run build && node smoke.mjs","build":"tsc","start":"node dist/index.js","prepublishOnly":"npm run build && node smoke.mjs"},"_npmUser":{"name":"vcastilho","email":"contato@castnexo.com.br"},"repository":{"url":"git+https://github.com/Castnexo/mcp-utm-builder.git","type":"git"},"_npmVersion":"11.9.0","description":"MCP server for Castnexo UTM Builder: create and organize UTM links, short links, clients and campaigns from an AI agent.","directories":{},"_nodeVersion":"24.14.0","dependencies":{"@modelcontextprotocol/sdk":"^1.0.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-utm-builder_0.1.0_1787920229948_0.275657980219012","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@castnexo/mcp-utm-builder","version":"0.1.1","description":"MCP server for Castnexo UTM Builder: create and organize UTM links, short links, clients and campaigns from an AI agent.","license":"MIT","type":"module","bin":{"mcp-utm-builder":"dist/index.js"},"main":"dist/index.js","engines":{"node":">=18"},"scripts":{"build":"tsc","test":"npm run build && node smoke.mjs","prepublishOnly":"npm run build && node smoke.mjs","start":"node dist/index.js"},"keywords":["mcp","model-context-protocol","utm","utm-builder","short-links","marketing","castnexo"],"repository":{"type":"git","url":"git+https://github.com/Castnexo/mcp-utm-builder.git"},"homepage":"https://utm.castnexo.com.br","dependencies":{"@modelcontextprotocol/sdk":"^1.0.0"},"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"gitHead":"7325c59f6c08fe2ab35f681f8d955f6d1f36318f","_id":"@castnexo/mcp-utm-builder@0.1.1","bugs":{"url":"https://github.com/Castnexo/mcp-utm-builder/issues"},"_nodeVersion":"24.14.0","_npmVersion":"11.9.0","dist":{"integrity":"sha512-axVEbgBTJi6iyNpV4F2Nm/CqF7O+N8389aMx+9PCsAwnxyiPKCZvba0nkB1PYGoX7FWqaOY6M0udQ0UV/9EbTg==","shasum":"1642ce0ec20a12a42a30db517d742515b3d02e78","tarball":"https://registry.npmjs.org/@castnexo/mcp-utm-builder/-/mcp-utm-builder-0.1.1.tgz","fileCount":4,"unpackedSize":27879,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIC+IyuwDTOXmWj0dijhWmc7uT7zV/MccqaAAmsUgXXDoAiB/6CLY8g9QUZycQriB1s7SWAuYK0FFSxOao7zvutJLTA=="}]},"_npmUser":{"name":"vcastilho","email":"contato@castnexo.com.br"},"directories":{},"maintainers":[{"name":"vcastilho","email":"contato@castnexo.com.br"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp-utm-builder_0.1.1_1787922355883_0.4748827722076876"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-28T12:30:29.766Z","modified":"2026-08-28T13:05:56.215Z","0.1.0":"2026-08-28T12:30:30.079Z","0.1.1":"2026-08-28T13:05:56.016Z"},"bugs":{"url":"https://github.com/Castnexo/mcp-utm-builder/issues"},"license":"MIT","homepage":"https://utm.castnexo.com.br","keywords":["mcp","model-context-protocol","utm","utm-builder","short-links","marketing","castnexo"],"repository":{"type":"git","url":"git+https://github.com/Castnexo/mcp-utm-builder.git"},"description":"MCP server for Castnexo UTM Builder: create and organize UTM links, short links, clients and campaigns from an AI agent.","maintainers":[{"name":"vcastilho","email":"contato@castnexo.com.br"}],"readme":"# @castnexo/mcp-utm-builder\n\nMCP server for [Castnexo UTM Builder](https://utm.castnexo.com.br). It lets an AI assistant create\nand organize your tracked links, short links, clients and campaigns.\n\nInstead of opening the app and filling the form once per link, you describe what you need and the\nassistant builds the links with consistent naming. That last part is the reason this exists:\nreports break when the same source shows up as `Instagram`, `instagram` and ` instagram `, and\nnaming by hand is where that drift comes from.\n\n## Requirements\n\n- Node.js 18 or newer\n- A Castnexo account with UTM Builder enabled\n- An API key, created in the app\n\n## Getting a key\n\n1. Open [utm.castnexo.com.br](https://utm.castnexo.com.br) and sign in\n2. Open the user menu, then **API keys**\n3. Click **Create key**, give it a name that says where it will run\n4. Copy the key right away. It is shown once and never again\n\nKeys are valid for 90 days and can be renewed from the same screen. You can hold up to 10 active\nkeys, and you can revoke any of them, or all at once, whenever you want.\n\n## Setup\n\n### Claude Code\n\n```bash\nclaude mcp add utm-builder \\\n  --env CASTNEXO_API_KEY=cnx_live_your_key_here \\\n  -- npx -y @castnexo/mcp-utm-builder\n```\n\n### Claude Desktop, Cursor, and other MCP clients\n\nAdd this to your MCP configuration file:\n\n```json\n{\n  \"mcpServers\": {\n    \"utm-builder\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@castnexo/mcp-utm-builder\"],\n      \"env\": {\n        \"CASTNEXO_API_KEY\": \"cnx_live_your_key_here\"\n      }\n    }\n  }\n}\n```\n\nRestart the client afterwards so it picks up the new server.\n\n## Tools\n\n| Tool | What it does |\n|---|---|\n| `list_clients` | Lists your clients |\n| `list_campaigns` | Lists campaigns, optionally filtered by client |\n| `list_links` | Lists saved links, optionally filtered by campaign or kind |\n| `get_stats` | Shows click counts for a link or a campaign |\n| `create_client` | Creates a client |\n| `create_campaign` | Creates a campaign inside a client |\n| `create_utm_link` | Creates a tracked link with UTM parameters |\n| `create_short_link` | Creates a short link with no UTM parameters |\n| `update_link` | Replaces an existing UTM link, keeping the same short code |\n| `update_short_link` | Updates a short link, changing only the fields you pass |\n\n### Things worth knowing\n\n**UTM values are normalized.** `Black Friday` is saved as `black-friday`, and `Promoção` as\n`promocao`. Accents come off, spaces become hyphens, and everything is lowercased, so one source\nstays one row in your reports.\n\n**Ad platform macros are left alone.** Anything containing `{` or `}`, such as\n`{{campaign.name}}` or `{keyword}`, is stored exactly as you wrote it. Those are literals the ad\nplatform substitutes at click time, and lowercasing them would break the substitution.\n\n**`update_link` REPLACES a link, it does not patch it.** Any UTM field you leave out is cleared,\nand leaving out `campaign_id` unfiles the link from its campaign. Ask the assistant to list the link\nfirst and send every field back, changing only what should change. Links carrying custom query\nparameters that are not UTMs should be edited in the web app, because those cannot be preserved\nthrough this tool.\n\n**That same tool changes a link that may already be published.** The short code stays the same, so\nanyone who already has the old link will land on the new destination. That is the point of the tool,\nand also the reason to be deliberate with it.\n\n**Short links are updated with `update_short_link`, which behaves the opposite way.** It patches:\nanything you leave out stays as it is. Use it for short links, and `update_link` for UTM links.\n\n**Listings are capped.** Every list tool returns 50 results by default, 200 at most, and says so\nwhen it cuts (`Showing 50 of 120 results.`). Raise it with `limit`, or narrow the filters. `get_stats`\nwith neither `link_id` nor `campaign_id` covers every link in the account, so pass a filter once the\naccount grows.\n\n## What this server cannot do\n\nNothing here deletes. There is no tool to remove a client, a campaign or a link, and the API\nrefuses those operations for API keys even if something tries to call them directly. Deleting is\ndone by you, in the web app.\n\nKey management is the same: a key cannot create, list or revoke another key. That only happens in\na signed-in browser session, so a leaked key cannot make itself permanent.\n\n## Configuration\n\n| Variable | Required | Default |\n|---|---|---|\n| `CASTNEXO_API_KEY` | yes | none |\n| `CASTNEXO_API_URL` | no | `https://api.castnexo.com.br` |\n\n## If something stops working\n\n| Message | What to do |\n|---|---|\n| Key was not accepted | Check `CASTNEXO_API_KEY`, or create a new key in the app |\n| Key expired | Renew it under Settings, API keys. The same key keeps working after renewal |\n| Key was revoked | Create a new one. Revoked keys do not come back |\n| Operation not available to API keys | Do it in the web app. Deleting and key management are session only |\n| Too many requests | Wait a moment. Limits are per key |\n\n## Security\n\nTreat the key like a password. Store it in your MCP client configuration or a password manager,\nnever in a repository. If you think a key leaked, revoke it in the app and create another. Revoking\ntakes effect on the next request.\n\nThis server sends the key only to the Castnexo API, over HTTPS, and never writes it to output.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}