@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
Maintainers
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
cursorto fetch the next page - Incremental sync — use the
sinceparameter 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/mcpFor local development — clone the repo and build:
npm install
npm run buildConfiguration
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
-yflag 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 # requiredCommands
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 --helpThe 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 --jsoncaytoo 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 --jsoncaytoo 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 --jsonPagination
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.jsYou can also use the MCP Inspector to test tools interactively:
npx @modelcontextprotocol/inspector node dist/index.jsSet 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