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

@caytoo/mcp

v1.3.14

Published

MCP server for the Caytoo External API — search brands, sponsorship deals, and market signals from any MCP-compatible AI client

Readme

Caytoo MCP Server & CLI

An MCP (Model Context Protocol) server that gives AI assistants direct access to the Caytoo External API — brands, sponsorship deals, and market signals. Also ships a caytoo CLI for searching directly from the terminal.


What it does

This server exposes 6 MCP tools that proxy the Caytoo REST API:

| Tool | Description | |------|-------------| | search_brands | Search brands by category, location, size, revenue, propensity, and deal/signal activity | | get_brand_filters | List all valid category and propensity filter values | | search_deals | Search sponsorship deals by brand, rights holder, value, type, and location | | get_deal_filters | List all valid deal filter values (fields, footprints, rights types, etc.) | | search_signals | Search brand activity signals (funding, launches, sponsorship activity) | | get_signal_filters | List all valid signal types and categories |

All search tools support:

  • Cursor-based pagination — pass the returned cursor to fetch the next page
  • Incremental sync — use the since parameter to fetch only records modified after a given timestamp
  • Rich filtering — multi-value array filters for categories, locations, ranges, and taxonomies

Prerequisites

  • Node.js 18 or later
  • A Caytoo API key (obtain from your organisation's API key management page)

Installation

For MCP clients (Claude Desktop, VS Code, Cursor) — no manual install needed. Use the npx configs below and the package is fetched automatically on first use.

For the CLI — install globally:

npm install -g @caytoo/mcp

For local development — clone the repo and build:

npm install
npm run build

Configuration

Authentication is configured via an environment variable — you do not need a config file:

| Variable | Required | Description | |----------|----------|-------------| | CAYTOO_API_KEY | Yes | API key from your Caytoo organisation settings | | CAYTOO_MAX_RETRIES | No | Max retries on 429 rate-limit responses (default: 3) |

The server applies exponential backoff with jitter on rate-limit (429) responses, honouring the Retry-After header returned by the API.


Where is this MCP server hosted?

Short answer: on your own machine (or your own server)

MCP servers are not hosted by Anthropic or Caytoo — you run them yourself. There are two deployment models:


Model 1 — Local / stdio (recommended for most users)

The server runs as a child process on the same machine as your AI client (Claude Desktop, VS Code + Claude extension, Cursor, etc.). Communication happens over stdin/stdout — no port, no network, no firewall rules needed.

Your API key stays on your machine and never leaves it. This is the standard deployment model for MCP servers.

Claude Desktop — add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "caytoo": {
      "command": "npx",
      "args": ["-y", "@caytoo/mcp"],
      "env": {
        "CAYTOO_API_KEY": "your-api-key-here"
      }
    }
  }
}

VS Code with Claude extension — add to .vscode/mcp.json in your workspace (or the global user settings.json):

{
  "servers": {
    "caytoo": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@caytoo/mcp"],
      "env": {
        "CAYTOO_API_KEY": "your-api-key-here"
      }
    }
  }
}

Cursor — add to ~/.cursor/mcp.json:

{
  "mcpServers": {
    "caytoo": {
      "command": "npx",
      "args": ["-y", "@caytoo/mcp"],
      "env": {
        "CAYTOO_API_KEY": "your-api-key-here"
      }
    }
  }
}

The -y flag prevents npx from prompting for confirmation, which would block the stdio channel that MCP communicates over.


Model 2 — Remote / HTTP (for teams or cloud deployments)

If multiple people or services need to share one MCP instance, you can run it as a persistent HTTP server. This requires changes to the transport layer (replace StdioServerTransport with StreamableHTTPServerTransport from the MCP SDK) and hosting it on infrastructure you control.

Suitable platforms:

  • Railway / Fly.io / Render — push to deploy, managed TLS, low ops overhead
  • AWS / GCP / Azure — ECS, Cloud Run, App Service for enterprise-grade deployments
  • Self-hosted VPS — run behind nginx with a process manager like PM2

In this mode the API key is stored as a secret/environment variable on the hosting platform, not on end-user machines.

Note: Remote MCP hosting is only needed when you want to share the server across multiple users or automate workflows from a server context. For individual developer use, the local stdio model above is simpler and more secure.


CLI

The package also installs a caytoo command for searching directly from the terminal.

npm install -g @caytoo/mcp
export CAYTOO_API_KEY=your-api-key-here   # required

Commands

caytoo brands search [options]   Search the brand database
caytoo brands filters            List valid brand filter values (live from API)

caytoo deals search [options]    Search sponsorship deals
caytoo deals filters             List valid deal filter values (live from API)

caytoo signals search [options]  Search market signals
caytoo signals filters           List valid signal filter values (live from API)

Getting full help

Each search subcommand has a full --help page with all options, filter format notes, and examples:

caytoo brands search --help
caytoo deals search --help
caytoo signals search --help

The filters commands fetch live values from the API — run them to see exactly what values are valid for category, signal type, rights type, and other dynamic filters before searching.


caytoo brands search

| Option | Description | |--------|-------------| | --primary-cat <values...> | Primary category filter — run caytoo brands filters to list valid values | | --secondary-cat <values...> | Secondary category filter | | --continent <values...> | Brand continent, e.g. Europe | | --country <values...> | Brand country, e.g. "United Kingdom" | | --region <values...> | Brand region, e.g. "Greater London" | | --city <values...> | Brand city, e.g. London | | --company-size <ranges...> | Employee count range in min-max format, e.g. 50-200, 1000-5000 | | --revenue <ranges...> | Annual revenue range in USD, e.g. 1000000-10000000 | | --propensity <values...> | VeryLow | Low | Moderate | High | VeryHigh — pass multiple to cover a range | | --active-signal | Only brands with currently active signals | | --active-deal | Only brands with currently active deals | | --active-signal-type <values...> | Require specific signal types (used with --active-signal) | | --active-since <date> | Brands with signals active since this date (ISO 8601) | | --since <date> | Incremental sync — records modified after this date (ISO 8601) | | --cursor <cursor> | Pagination cursor from a previous response | | --page-size <n> | Results per page, 1–100 (default: 20) | | --sort <field> | brandname | revenue | employees | yearfounded | category | subcategory | location | propensity | | --sort-order <order> | asc | desc (default: asc) | | --full | Show full details: description, website, employee count, year founded | | --json | Output raw JSON |

# High-propensity brands in the UK
caytoo brands search --country "United Kingdom" --propensity High VeryHigh

# Sports brands with full detail view
caytoo brands search --primary-cat "Sports & Fitness" --page-size 50 --full

# Brands with currently active signals since start of 2024
caytoo brands search --active-signal --active-since 2024-01-01

# Large brands sorted by revenue descending
caytoo brands search --company-size 1000-5000 --sort revenue --sort-order desc

# Raw JSON for scripting
caytoo brands search --country Germany --json | jq '.data[].name'

caytoo brands filters

Returns all valid values for --primary-cat, --secondary-cat, and --propensity.

caytoo brands filters
caytoo brands filters --json

caytoo deals search

| Option | Description | |--------|-------------| | --brand-id <ids...> | Filter by brand ID(s) — numeric, from brand search results | | --rights-holder-id <ids...> | Filter by rights holder ID(s) — numeric | | --primary-cat <values...> | Brand primary category — run caytoo deals filters to list valid values | | --secondary-cat <values...> | Brand secondary category | | --brand-country <values...> | Brand's country, e.g. "United Kingdom" | | --brand-city <values...> | Brand's city | | --brand-continent <values...> | Brand's continent | | --brand-region <values...> | Brand's region | | --rh-country <values...> | Rights holder's country | | --rh-city <values...> | Rights holder's city | | --rh-continent <values...> | Rights holder's continent | | --rh-region <values...> | Rights holder's region | | --revenue <ranges...> | Brand annual revenue range in USD, e.g. 1000000-10000000 | | --brand-size <ranges...> | Brand employee count range, e.g. 50-200 | | --deal-value <ranges...> | Deal value range — run caytoo deals filters to see valid bands | | --field <values...> | Rights holder sector, e.g. Football, Music — see caytoo deals filters | | --footprint <values...> | Geographic scope, e.g. Global, National — see caytoo deals filters | | --rights-type <values...> | Type of rights, e.g. Naming, Title, Shirt — see caytoo deals filters | | --motivation <values...> | Deal motivation/objective — see caytoo deals filters | | --gender <values...> | Audience gender target — see caytoo deals filters | | --deal-type <values...> | Deal type classification — see caytoo deals filters | | --from <date> | Deal created on or after this date (ISO 8601) | | --to <date> | Deal created on or before this date (ISO 8601) | | --deal-end-from <date> | Deal ending on or after this date (ISO 8601) | | --deal-end-to <date> | Deal ending on or before this date (ISO 8601) | | --since <date> | Incremental sync — records modified after this date (ISO 8601) | | --cursor <cursor> | Pagination cursor from a previous response | | --page-size <n> | Results per page, 1–100 (default: 20) | | --sort <field> | Sort field (default: date) | | --sort-order <order> | asc | desc (default: desc — newest first) | | --full | Show full details: summary, objective, activation, footprint, duration | | --json | Output raw JSON |

# All deals for a specific brand
caytoo deals search --brand-id 12345 --full

# Naming rights deals since 2024
caytoo deals search --rights-type Naming --from 2024-01-01

# Football deals in the UK with full details
caytoo deals search --field Football --rh-country "United Kingdom" --full

# US brand deals, oldest first
caytoo deals search --brand-country "United States" --sort-order asc

# Raw JSON for scripting
caytoo deals search --brand-id 12345 --json | jq '.data[].value'

caytoo deals filters

Returns all valid values for --field, --footprint, --rights-type, --motivation, --gender, --deal-value, and categories.

caytoo deals filters
caytoo deals filters --json

caytoo signals search

| Option | Description | |--------|-------------| | --brand-id <ids...> | Filter by brand ID(s) — numeric, from brand search results | | --signal-type <values...> | Type of signal — run caytoo signals filters to list all types | | --primary-cat <values...> | Brand primary category — run caytoo signals filters to list valid values | | --secondary-cat <values...> | Brand secondary category | | --country <values...> | Country where the signal occurred, e.g. "United States" | | --continent <values...> | Continent where the signal occurred | | --region <values...> | Region where the signal occurred | | --city <values...> | City where the signal occurred | | --brand-country <values...> | Brand's HQ country | | --brand-continent <values...> | Brand's HQ continent | | --brand-region <values...> | Brand's HQ region | | --brand-city <values...> | Brand's HQ city | | --company-size <ranges...> | Brand employee count range, e.g. 50-200 | | --revenue <ranges...> | Brand annual revenue range in USD, e.g. 1000000-10000000 | | --from <date> | Signals published on or after this date (ISO 8601) | | --to <date> | Signals published on or before this date (ISO 8601) | | --since <date> | Incremental sync — records modified after this date (different from --from) | | --cursor <cursor> | Pagination cursor from a previous response | | --page-size <n> | Results per page, 1–100 (default: 20) | | --sort <field> | Sort field (default: date) | | --sort-order <order> | asc | desc (default: desc — newest first) | | --full | Show full details: summary, objective, activations, source URLs | | --json | Output raw JSON |

# All signals for a specific brand
caytoo signals search --brand-id 12345

# US funding rounds
caytoo signals search --signal-type "Funding Round" --country "United States"

# Sports & Fitness signals in 2024, full detail
caytoo signals search --primary-cat "Sports & Fitness" --from 2024-01-01 --full

# Partnership signals from UK-headquartered brands
caytoo signals search --brand-country "United Kingdom" --signal-type "Partnership"

# Raw JSON for scripting
caytoo signals search --brand-id 12345 --json | jq '.data[].headline'

caytoo signals filters

Returns all valid values for --signal-type, --primary-cat, and --secondary-cat.

caytoo signals filters
caytoo signals filters --json

Pagination

When results span multiple pages, the CLI prints the exact command to run for the next page — copy and paste it. Always keep --page-size consistent across pages.

# First page
caytoo brands search --country "United Kingdom" --page-size 20

# Output includes:
# Next page: caytoo brands search --country "United Kingdom" --page-size 20 --cursor "eyJ..."

# Second page — just copy that line and run it
caytoo brands search --country "United Kingdom" --page-size 20 --cursor "eyJ..."

Running locally (test / development)

# Copy and fill in your credentials
cp .env.example .env

# Build and start (reads from .env via your shell)
npm run build
CAYTOO_API_KEY=your-key node dist/index.js

You can also use the MCP Inspector to test tools interactively:

npx @modelcontextprotocol/inspector node dist/index.js

Set CAYTOO_API_KEY in the Inspector's environment variables panel.


Tool reference

search_brands

Search the Caytoo brand database.

| Parameter | Type | Description | |-----------|------|-------------| | primaryCat | string[] | Filter by primary category | | secondaryCat | string[] | Filter by secondary category | | locContinent / locCountry / locRegion / locCity | string[] | Brand location filters | | companySizeRanges | string[] | Employee count ranges, e.g. "50-200" | | revenueRanges | string[] | Revenue ranges (USD), e.g. "1000000-10000000" | | propensity | enum[] | VeryLow | Low | Moderate | High | VeryHigh | | activeSignal | boolean | Only brands with active signals | | activeDeal | boolean | Only brands with active deals | | activeSignalTypes | string[] | Combined with activeSignal=true | | activeSince | ISO 8601 | Brands with signals active since this date | | since | ISO 8601 | Incremental sync — records modified after this timestamp | | cursor | string | Next-page cursor from previous response | | pageSize | 1–100 | Default: 20 | | sortField | string | brandname | revenue | employees | yearfounded | category | subcategory | location | propensity | | sortOrder | asc\|desc | Default: asc | | includeTotal | boolean | Exact total count (slower) |


search_deals

Search sponsorship deals.

| Parameter | Type | Description | |-----------|------|-------------| | createdFrom / createdTo | ISO 8601 | Deal creation date range | | dealEndFrom / dealEndTo | ISO 8601 | Deal end date range | | primaryCat / secondaryCat | string[] | Category filters | | brandLoc* / rhLoc* | string[] | Brand/rights-holder location filters | | revenueRange / brandSize / dealValue | string[] | Range filters in min-max format | | fields / footprint / rightsType / motivation / gender / dealType | string[] | Taxonomy filters (see get_deal_filters) | | brandIds / rightsHolderIds | number[] | Filter by specific IDs | | since | ISO 8601 | Incremental sync | | cursor / pageSize / sortField / sortOrder / includeTotal | — | Pagination & sorting |


search_signals

Search brand market intelligence signals.

| Parameter | Type | Description | |-----------|------|-------------| | brandIds | number[] | Restrict to specific brands | | from / to | ISO 8601 | Signal article date range | | primaryCat / secondaryCat | string[] | Category filters | | locContinent / locCountry / locRegion / locCity | string[] | Signal location | | brandLoc* | string[] | Brand HQ location | | companySizeRange / revenueRange | string[] | Brand size/revenue ranges | | signalType | string[] | e.g. "Funding", "Product Launch" (see get_signal_filters) | | since | ISO 8601 | Incremental sync (distinct from from) | | cursor / pageSize / sortField / sortOrder / includeTotal | — | Pagination & sorting |


Rate limits

The Caytoo API enforces:

  • 5,000 requests per hour per organisation
  • 100 requests per 10 seconds (burst protection)

This server automatically retries on 429 responses using exponential backoff with jitter, honouring the Retry-After header. Configure the retry count via CAYTOO_MAX_RETRIES.


Project structure

caytoo/mcp/
├── src/
│   ├── index.ts              # MCP server entry point (bin: caytoo-mcp)
│   ├── client.ts             # Caytoo HTTP client (auth, retries, pagination)
│   ├── types.ts              # TypeScript interfaces for all API models
│   ├── formatter.ts          # Response formatting for MCP tools
│   ├── tools/
│   │   ├── brands.ts         # search_brands + get_brand_filters tools
│   │   ├── deals.ts          # search_deals + get_deal_filters tools
│   │   ├── signals.ts        # search_signals + get_signal_filters tools
│   │   ├── lookups.ts        # Convenience tools (get_signals_for_brand, etc.)
│   │   └── helpers.ts        # Shared Zod schema helpers
│   └── cli/
│       ├── index.ts          # CLI entry point (bin: caytoo)
│       ├── output.ts         # Terminal output formatting
│       └── commands/
│           ├── brands.ts     # caytoo brands search/filters
│           ├── deals.ts      # caytoo deals search/filters
│           └── signals.ts    # caytoo signals search/filters
├── dist/                     # Compiled output (after npm run build)
├── .env.example              # Environment variable template
├── package.json
├── tsconfig.json
└── README.md