@mambalabsdev/mcp-talent-agency-lookup 1.0.1 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +13 -7
  2. package/build/index.js +56 -20
  3. package/package.json +4 -3
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Influencer Talent Agency Lookup MCP Server
2
2
 
3
- [![Smithery](https://smithery.ai/badge/mambabuilt/mcp-talent-agency-lookup)](https://smithery.ai/servers/mambabuilt/mcp-talent-agency-lookup) [![Glama score](https://glama.ai/mcp/servers/mambalabsdev/mcp-talent-agency-lookup/badges/score.svg)](https://glama.ai/mcp/servers/mambalabsdev/mcp-talent-agency-lookup) [![MCP Registry](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fregistry.modelcontextprotocol.io%2Fv0%2Fservers%3Fsearch%3Dcom.mambabuilt%252Fmcp-talent-agency-lookup%26limit%3D1&query=%24.servers%5B0%5D._meta%5B%22io.modelcontextprotocol.registry%2Fofficial%22%5D.status&label=mcp%20registry&color=blue)](https://registry.modelcontextprotocol.io/v0/servers?search=com.mambabuilt/mcp-talent-agency-lookup&limit=1) [![npm version](https://img.shields.io/npm/v/@mambalabsdev/mcp-talent-agency-lookup)](https://www.npmjs.com/package/@mambalabsdev/mcp-talent-agency-lookup) [![npm downloads](https://img.shields.io/npm/dm/@mambalabsdev/mcp-talent-agency-lookup)](https://www.npmjs.com/package/@mambalabsdev/mcp-talent-agency-lookup) [![license](https://img.shields.io/github/license/mambalabsdev/mcp-talent-agency-lookup)](https://github.com/mambalabsdev/mcp-talent-agency-lookup/blob/main/LICENSE) [![mcpservers.org](https://img.shields.io/badge/mcpservers.org-listed-blue)](https://mcpservers.org/servers/mambalabsdev/mcp-talent-agency-lookup)
3
+ [![Glama score](https://glama.ai/mcp/servers/mambalabsdev/mcp-talent-agency-lookup/badges/score.svg)](https://glama.ai/mcp/servers/mambalabsdev/mcp-talent-agency-lookup) [![MCP Registry](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fregistry.modelcontextprotocol.io%2Fv0%2Fservers%3Fsearch%3Dcom.mambabuilt%252Fmcp-talent-agency-lookup%26limit%3D1&query=%24.servers%5B0%5D._meta%5B%22io.modelcontextprotocol.registry%2Fofficial%22%5D.status&label=mcp%20registry&color=blue)](https://registry.modelcontextprotocol.io/v0/servers?search=com.mambabuilt/mcp-talent-agency-lookup&limit=1) [![npm version](https://img.shields.io/npm/v/@mambalabsdev/mcp-talent-agency-lookup)](https://www.npmjs.com/package/@mambalabsdev/mcp-talent-agency-lookup) [![npm downloads](https://img.shields.io/npm/dm/@mambalabsdev/mcp-talent-agency-lookup)](https://www.npmjs.com/package/@mambalabsdev/mcp-talent-agency-lookup) [![license](https://img.shields.io/github/license/mambalabsdev/mcp-talent-agency-lookup)](https://github.com/mambalabsdev/mcp-talent-agency-lookup/blob/main/LICENSE) [![mcpservers.org](https://img.shields.io/badge/mcpservers.org-listed-blue)](https://mcpservers.org/servers/mambalabsdev/mcp-talent-agency-lookup)
4
4
 
5
5
  MCP server for the Mamba Labs [Influencer Talent Agency Lookup](https://apify.com/mambalabs/talent-agency-lookup) actor on Apify.
6
6
 
@@ -28,13 +28,17 @@ npx -y @mambalabsdev/mcp-talent-agency-lookup
28
28
 
29
29
  Get an Apify token at [console.apify.com/account/integrations](https://console.apify.com/account/integrations).
30
30
 
31
- ## Tool
31
+ ## Tools
32
32
 
33
- ### `lookup_influencer_talent_agency`
33
+ | Tool | Direction | Inputs |
34
+ | --- | --- | --- |
35
+ | `lookup_agency_for_creator` | Creator to agency: one row per creator with the agency that represents them | `handles`, `platforms`, `escalate_on_block`, `batch_size`, `contribute_to_shared_pool` |
36
+ | `list_agency_roster` | Agency to roster: one row per creator on the agency's public roster | `agency_domains`, `agency_names`, `render_unreadable_pages`, `contribute_to_shared_pool` |
37
+ | `lookup_influencer_talent_agency` | Both directions in one call, every actor input | all of the inputs below |
34
38
 
35
- Match an influencer to their talent agency, or an agency to its public creator roster.
39
+ All three call the same actor, so the pricing below applies to each. The two directional tools are the simpler choice when only one direction is needed; the combined tool is kept so existing callers keep working.
36
40
 
37
- Pass `handles` for creator to agency, or `agency_domains` or `agency_names` for agency to roster. Both directions can run in one call.
41
+ ### Inputs
38
42
 
39
43
  | Input | Type | Required | Notes |
40
44
  | --- | --- | --- | --- |
@@ -44,7 +48,7 @@ Pass `handles` for creator to agency, or `agency_domains` or `agency_names` for
44
48
  | `agency_names` | array | no | Agency to roster by name when you do not have the domain. Exact or partial name match against the list. |
45
49
  | `render_unreadable_pages` | boolean | no | Off by default. Some agency roster pages build their talent grid in the browser and return an empty shell to a plain fetch, so the roster reads as empty. Turn this on to render those pages in a headless browser and read the roster from the rendered page. Charged per page rendered (event browser-render) to cover the browser compute, and only when the rendered page comes back readable. A page that answers with a bot challenge is recorded as blocked and is never rendered. Default `false`. |
46
50
  | `escalate_on_block` | boolean | no | On by default. A profile fetch that comes back as a bot detection page is retried once over the residential proxy. On Instagram the bio, bio link, and following are read from the profile page over residential when the embed and the datacenter API did not carry them, and a page that comes back readable charges instagram-bio-fetch ($0.010). Uncheck it to never pay that event: a blocked profile then returns a labeled error row, and Instagram rows keep an empty bio and bio link on about half of the reads. Default `true`. |
47
- | `batch_size` | integer | no | Rows fetched at once. Leave empty for the measured per platform default; the measurement is in the README. Higher is faster and, above the measured point, loses rows. |
51
+ | `batch_size` | integer | no | Rows fetched at once. Leave empty for the measured per platform default; the measurement is in the [actor README](https://apify.com/mambalabs/talent-agency-lookup#-batch-or-single). Higher is faster and, above the measured point, loses rows. |
48
52
  | `contribute_to_shared_pool` | boolean | no | On by default. The run contributes the public records it finds to a shared creator and agency pool that all users of this actor read from, so a later run reads what this one found. Only public data that is already in your own output rows is sent: nothing from your Apify account, your input list, your API keys, or your own notes. Nothing is charged for a contribution. Turn this off and the run still reads the pool and writes nothing to it. Default: true. |
49
53
 
50
54
  Nothing is required, but a call with no `handles`, no `agency_domains`, and no `agency_names` has nothing to look up and the run fails with a message saying so.
@@ -60,11 +64,13 @@ Influencer Talent Agency Lookup is pay per event on Apify. Every price below is
60
64
  | `browser-render` | Browser render | $0.004 | Once per agency roster page rendered in the headless browser because the plain fetch returned an empty shell, and only when the rendered page came back readable. Only when `render_unreadable_pages` is on. |
61
65
  | `instagram-bio-fetch` | Instagram bio fetch | $0.01 | Once per Instagram profile row when the bio, bio link, and following were read from the profile page over the residential proxy and came back readable. Only when `escalate_on_block` is on. |
62
66
 
67
+ `apify-actor-start`, the start event Apify adds to pay per event actors by default, is not on this actor's pricing record. The run overhead is billed once per run through the actor's own `actor-start` event above, at $0.001, so a run is never charged for its start twice.
68
+
63
69
  ## Reading the output
64
70
 
65
71
  Every row carries `agency_match_method`: `email_domain_exact`, `email_domain_parent`, `public_roster`, `bio_wording`, or `no_match`. A `no_match` row names the email domains it tried in `error_reason`. Every row also carries `row_status` and `error_reason`, so a creator or an agency the actor could not read comes back as a row saying why, not as a gap in the list. Filter on `row_status` before loading a table.
66
72
 
67
- Coverage is partial by construction. The bundled list holds 143 agencies and 557 roster creators, seeded from 13 public directories, and it grows through the shared pool.
73
+ Coverage is partial by construction. The bundled list held 143 agencies and 557 roster creators when the actor was published, seeded from 13 public directories, and it grows through the shared pool.
68
74
 
69
75
  ## What this actor shares
70
76
 
package/build/index.js CHANGED
@@ -171,28 +171,64 @@ const server = new McpServer({
171
171
  version: pkg.version,
172
172
  });
173
173
  // Influencer Talent Agency Lookup (immutable actor ID zCuX4Mgyg6JvXgGzd)
174
- server.registerTool("lookup_influencer_talent_agency", {
175
- title: "Look Up an Influencer's Talent Agency or an Agency's Roster",
176
- description: "Works in two directions. Creator to agency: pass creator handles or profile URLs and get one row per creator with the talent agency that represents them, its domain, its public contact, and agency_match_method (email_domain_exact, email_domain_parent, public_roster, bio_wording, or no_match with the email domains tried in error_reason). Agency to roster: pass agency domains or agency names and get one row per creator on the agency's public roster, with platform, handle, and profile URL. The agency list is seeded from 13 public directories and holds 143 agencies and 557 roster creators; coverage is partial and every row says how it matched. Supports TikTok, Instagram, YouTube, Pinterest, Twitch, Threads, and podcasts. Charges $0.001 per run plus $0.008 per row returned, $0.004 per agency roster page rendered in the headless browser when render_unreadable_pages is on and the rendered page comes back readable, and $0.01 per Instagram bio fetch when one is needed. Contributes the public records it finds to a shared creator and agency pool that all users of this actor read from, so a later run reads what this one found; `contribute_to_shared_pool` is on by default and turning it off leaves the run reading the pool and writing nothing. Only public data already in the returned rows is contributed, nothing from your Apify account or your input, and a contribution is not charged. Requires an APIFY_TOKEN and consumes Apify credits. Read only.",
177
- annotations: {
178
- title: "Look Up an Influencer's Talent Agency or an Agency's Roster",
179
- readOnlyHint: true,
180
- destructiveHint: false,
181
- idempotentHint: true,
182
- openWorldHint: true,
174
+ const ACTOR_ID = "zCuX4Mgyg6JvXgGzd";
175
+ const ACTOR_LABEL = "Influencer Talent Agency Lookup";
176
+ // Input fields, defined once and shared by the three tools. Descriptions mirror
177
+ // the live actor input schema (test/fixtures/live-input-schema.json).
178
+ const fields = {
179
+ handles: z.array(z.string()).optional().describe("One per line. A profile URL on any supported platform (https://www.tiktok.com/@name, https://www.instagram.com/name/, https://www.youtube.com/@name, a Pinterest, Twitch, or Threads profile, an Apple Podcasts show page, or a Spotify show), or platform:@handle (tiktok:@name). A bare @handle needs `platforms` and is looked up on each listed platform. One entry is a single run; a list is a batch. Duplicates are removed before any fetch."),
180
+ platforms: z.array(z.enum(["tiktok", "instagram", "youtube", "pinterest", "twitch", "threads", "podcast"])).optional().describe("Which platforms a bare @handle is looked up on. A full profile URL carries its own platform and ignores this. This actor does not search; pass the creators you want read. Supported: TikTok, Instagram, YouTube, Pinterest, Twitch, Threads, and podcasts. Not X, not Facebook pages, not LinkedIn."),
181
+ agency_domains: z.array(z.string()).optional().describe("Agency to roster: one domain per line (for example viralnation.com). Returns one row per creator on the agency's public roster."),
182
+ agency_names: z.array(z.string()).optional().describe("Agency to roster by name when you do not have the domain. Exact or partial name match against the list."),
183
+ render_unreadable_pages: z.boolean().optional().describe("Off by default. Some agency roster pages build their talent grid in the browser and return an empty shell to a plain fetch, so the roster reads as empty. Turn this on to render those pages in a headless browser and read the roster from the rendered page. Charged per page rendered (event browser-render) to cover the browser compute, and only when the rendered page comes back readable. A page that answers with a bot challenge is recorded as blocked and is never rendered."),
184
+ escalate_on_block: z.boolean().optional().describe("On by default. A profile fetch that comes back as a bot detection page is retried once over the residential proxy. On Instagram the bio, bio link, and following are read from the profile page over residential when the embed and the datacenter API did not carry them, and a page that comes back readable charges instagram-bio-fetch ($0.010). Uncheck it to never pay that event: a blocked profile then returns a labeled error row, and Instagram rows keep an empty bio and bio link on about half of the reads."),
185
+ batch_size: z.number().int().min(1).max(10).optional().describe("Rows fetched at once. Leave empty for the measured per platform default; the measurement is in the actor README, https://apify.com/mambalabs/talent-agency-lookup#-batch-or-single. Higher is faster and, above the measured point, loses rows."),
186
+ // Shared pool toggle. The actor input field shipped in build 0.1.11; this mirror exists so an
187
+ // MCP caller can turn the contribution off.
188
+ contribute_to_shared_pool: z.boolean().optional().describe("On by default. The run contributes the public records it finds to a shared creator and agency pool that all users of this actor read from, so a later run reads what this one found. Only public data that is already in your own output rows is sent: nothing from your Apify account, your input list, your API keys, or your own notes. Nothing is charged for a contribution. Turn this off and the run still reads the pool and writes nothing to it. Default: true."),
189
+ };
190
+ const PRICING = "Charges $0.001 per run (actor-start) plus $0.008 per row returned (agency-lookup), $0.004 per agency roster page rendered in the headless browser when render_unreadable_pages is on and the page comes back readable (browser-render), and $0.01 per Instagram bio fetch over the residential proxy when escalate_on_block is on and one is needed (instagram-bio-fetch).";
191
+ const POOL = "Contributes the public records it finds to a shared creator and agency pool that all users of this actor read from; set contribute_to_shared_pool to false to read the pool and write nothing. A contribution is not charged.";
192
+ const COVERAGE = "The agency list is seeded from 13 public directories (143 agencies and 557 roster creators when the actor was published) and grows through the shared pool; coverage is partial and every row says how it matched.";
193
+ const LIMITS = "It does not search for creators and does not read X, Facebook pages, or LinkedIn. Requires an APIFY_TOKEN and consumes Apify credits. Read only.";
194
+ const annotations = (title) => ({
195
+ title,
196
+ readOnlyHint: true,
197
+ destructiveHint: false,
198
+ idempotentHint: true,
199
+ openWorldHint: true,
200
+ });
201
+ const callActor = (args) => runActor(ACTOR_ID, ACTOR_LABEL, compact(args));
202
+ server.registerTool("lookup_agency_for_creator", {
203
+ title: "Find the Talent Agency Behind an Influencer",
204
+ description: `Creator to agency. Pass creator handles or profile URLs (TikTok, Instagram, YouTube, Pinterest, Twitch, Threads, or a podcast) and get one row per creator with the talent agency that represents them, its domain, its public contact, and agency_match_method (email_domain_exact, email_domain_parent, public_roster, bio_wording, or no_match with the email domains tried in error_reason). Use list_agency_roster for the other direction. ${COVERAGE} ${PRICING} ${POOL} ${LIMITS}`,
205
+ annotations: annotations("Find the Talent Agency Behind an Influencer"),
206
+ inputSchema: {
207
+ handles: fields.handles,
208
+ platforms: fields.platforms,
209
+ escalate_on_block: fields.escalate_on_block,
210
+ batch_size: fields.batch_size,
211
+ contribute_to_shared_pool: fields.contribute_to_shared_pool,
183
212
  },
213
+ }, async (args) => callActor(args));
214
+ server.registerTool("list_agency_roster", {
215
+ title: "List an Influencer Talent Agency's Roster",
216
+ description: `Agency to roster. Pass agency domains or agency names and get one row per creator on the agency's public roster, with platform, handle, and profile URL. Use lookup_agency_for_creator for the other direction. ${COVERAGE} ${PRICING} ${POOL} ${LIMITS}`,
217
+ annotations: annotations("List an Influencer Talent Agency's Roster"),
184
218
  inputSchema: {
185
- handles: z.array(z.string()).optional().describe("One per line. A profile URL on any supported platform (https://www.tiktok.com/@name, https://www.instagram.com/name/, https://www.youtube.com/@name, a Pinterest, Twitch, or Threads profile, an Apple Podcasts show page, or a Spotify show), or platform:@handle (tiktok:@name). A bare @handle needs `platforms` and is looked up on each listed platform. One entry is a single run; a list is a batch. Duplicates are removed before any fetch."),
186
- platforms: z.array(z.enum(["tiktok", "instagram", "youtube", "pinterest", "twitch", "threads", "podcast"])).optional().describe("Which platforms a bare @handle is looked up on. A full profile URL carries its own platform and ignores this. This actor does not search; pass the creators you want read. Supported: TikTok, Instagram, YouTube, Pinterest, Twitch, Threads, and podcasts. Not X, not Facebook pages, not LinkedIn."),
187
- agency_domains: z.array(z.string()).optional().describe("Agency to roster: one domain per line (for example viralnation.com). Returns one row per creator on the agency's public roster."),
188
- agency_names: z.array(z.string()).optional().describe("Agency to roster by name when you do not have the domain. Exact or partial name match against the list."),
189
- render_unreadable_pages: z.boolean().optional().describe("Off by default. Some agency roster pages build their talent grid in the browser and return an empty shell to a plain fetch, so the roster reads as empty. Turn this on to render those pages in a headless browser and read the roster from the rendered page. Charged per page rendered (event browser-render) to cover the browser compute, and only when the rendered page comes back readable. A page that answers with a bot challenge is recorded as blocked and is never rendered."),
190
- escalate_on_block: z.boolean().optional().describe("On by default. A profile fetch that comes back as a bot detection page is retried once over the residential proxy. On Instagram the bio, bio link, and following are read from the profile page over residential when the embed and the datacenter API did not carry them, and a page that comes back readable charges instagram-bio-fetch ($0.010). Uncheck it to never pay that event: a blocked profile then returns a labeled error row, and Instagram rows keep an empty bio and bio link on about half of the reads."),
191
- batch_size: z.number().int().min(1).max(10).optional().describe("Rows fetched at once. Leave empty for the measured per platform default; the measurement is in the README. Higher is faster and, above the measured point, loses rows."),
192
- // Shared pool toggle. The actor input field shipped in build 0.1.11; this mirror exists so an
193
- // MCP caller can turn the contribution off.
194
- contribute_to_shared_pool: z.boolean().optional().describe("On by default. The run contributes the public records it finds to a shared creator and agency pool that all users of this actor read from, so a later run reads what this one found. Only public data that is already in your own output rows is sent: nothing from your Apify account, your input list, your API keys, or your own notes. Nothing is charged for a contribution. Turn this off and the run still reads the pool and writes nothing to it. Default: true."),
219
+ agency_domains: fields.agency_domains,
220
+ agency_names: fields.agency_names,
221
+ render_unreadable_pages: fields.render_unreadable_pages,
222
+ contribute_to_shared_pool: fields.contribute_to_shared_pool,
195
223
  },
196
- }, async (args) => runActor("zCuX4Mgyg6JvXgGzd", "Influencer Talent Agency Lookup", compact(args)));
224
+ }, async (args) => callActor(args));
225
+ // The original combined tool, kept so existing callers keep working. It runs
226
+ // both directions in one call and exposes every buyer input of the live actor.
227
+ server.registerTool("lookup_influencer_talent_agency", {
228
+ title: "Look Up an Influencer's Talent Agency or an Agency's Roster",
229
+ description: `Both directions in one call: handles for creator to agency, agency_domains or agency_names for agency to roster. Prefer lookup_agency_for_creator or list_agency_roster when only one direction is needed. ${COVERAGE} ${PRICING} ${POOL} ${LIMITS}`,
230
+ annotations: annotations("Look Up an Influencer's Talent Agency or an Agency's Roster"),
231
+ inputSchema: fields,
232
+ }, async (args) => callActor(args));
197
233
  const transport = new StdioServerTransport();
198
234
  await server.connect(transport);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mambalabsdev/mcp-talent-agency-lookup",
3
3
  "displayName": "Influencer Talent Agency Lookup",
4
- "version": "1.0.1",
4
+ "version": "1.1.1",
5
5
  "description": "MCP server for the Mamba Labs Influencer Talent Agency Lookup actor on Apify. Creator handles in, the talent agency behind each one out, or an agency in, its public roster out.",
6
6
  "type": "module",
7
7
  "bin": {
@@ -10,7 +10,8 @@
10
10
  "scripts": {
11
11
  "build": "tsc && chmod +x build/index.js",
12
12
  "test": "npm run build && node --test test/*.test.js",
13
- "prepublishOnly": "npm run build"
13
+ "prepublishOnly": "npm run build",
14
+ "sync-fixture": "node scripts/sync-input-schema-fixture.mjs"
14
15
  },
15
16
  "keywords": [
16
17
  "mcp",
@@ -45,7 +46,7 @@
45
46
  "node": ">=18"
46
47
  },
47
48
  "dependencies": {
48
- "@modelcontextprotocol/sdk": "^1.12.0",
49
+ "@modelcontextprotocol/sdk": "^1.32.0",
49
50
  "zod": "^4.5.4"
50
51
  },
51
52
  "devDependencies": {