Career Change Signal Engine MCP Server
Generates HubSpot-ready payloads for each change row, so detected job changes (who left, who landed where, who replaced them) can be pushed directly into HubSpot workflows and records.
Produces Slack-formatted payloads for each detected career-change signal row, enabling change alerts to be posted to Slack channels.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Career Change Signal Engine MCP ServerCheck my watch list and tell me who changed jobs since last run."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Career Change Signal Engine MCP Server
An MCP server for the Mamba Labs Career Change Signal Engine actor on Apify. Career Change Signal Engine reads the people on your watch list and returns only what changed since you last checked: who left, who landed where, who replaced them, and who started after a role closed. Every row says how the person was matched, which source answered, and how old that source is.
What's Inside
Related MCP server: Competiflow MCP Server
What it does
Read a watch list of contacts and return only what changed since the last run: who left, who landed where, who replaced them, and who started after a role closed. Each row carries evidence, a source date, a segment, a first line draft, and Slack, HubSpot, HeyReach, and Instantly payloads. Pass people (required) and, optionally, replies, bounces, posting changes, suppression, and your own provider keys in providerKeys; it never fetches LinkedIn and holds no key of its own. State is kept per watch_list_id. A run that does not succeed is returned as an error with its run ID. Requires an APIFY_TOKEN and consumes Apify credits per call.
All of the work runs on Apify. This package is a thin client that starts the actor run, waits for it, and hands back the dataset rows.
Quick start
You need Node.js 18 or newer and an Apify account with an API token.
Add this to your Claude Desktop config (claude_desktop_config.json), Cursor, or any MCP client:
{
"mcpServers": {
"mamba-career-change-signal-engine": {
"command": "npx",
"args": [
"-y",
"@mambalabsdev/mcp-career-change-signal-engine"
],
"env": {
"APIFY_TOKEN": "your-apify-token"
}
}
}
}Restart the client. The watch_career_changes tool appears.
Prerequisites
Node.js 18 or newer.
An Apify API token from console.apify.com/account/integrations, set as
APIFY_TOKEN. The server lists its tool without a token; a call needs one.
Example prompts
"Check my 50 past champions and tell me who left and where they landed."
"Run my watch list and draft a first line for each person who changed jobs."
Tool
watch_career_changes. One tool. Example arguments:
{
"people": [
{
"person_name": "Jane Doe",
"company_domain": "example.com",
"company_name": "Example Inc",
"title": "Head of Content",
"external_id": "example-1"
}
],
"watch_list_id": "default"
}Inputs
Every buyer facing input of the live actor, unchanged. Omitted inputs take the actor's own defaults.
Input | Type | Required | Description |
| array | yes | Your watch list, one object per person: person_name, profile_url (optional), company_domain, company_name, title, work_email, relationship (prospect, mgl, deal_contact, customer_champion), external_id, crm_id, deal_id, known_history (a HeyReach copy, a Proofed LinkedIn reader row, or generic roles), last_reading (with state_source caller). The engine reads only these people. At most max_people_per_run per run. |
| string | no | Names the list. State is kept per watch list id when state_source is actor. |
| string | no | actor: the engine keeps state between runs in a named store. caller: you send last_reading per person and keep state yourself. |
| string | no | stored_first: your known_history first, then your keys. live_only: ignore known_history. stored_only: only known_history, no key calls. |
| string | no | report: the first run returns every change it finds. baseline: the first run stores state and returns nothing, charging only contact_checked. |
| integer | no | A list longer than this fails the run before any read or charge. Default 150, at most 1,000. |
| object | no | Your own keys: serper or serpapi (web search), prospeo, bounceban (verifier), findymail, exa. Never written to state, output, logs, or the webhook. Your own key, sent as a run input; never stored by the actor. |
| string | no | Optional: the dataset id of a Proofed LinkedIn reader run on the same Apify account. Rows join to people by profile URL. |
| array | no | Optional reply texts: external_id or work_email or profile_url, text, received_at, channel, is_auto_reply. Text is classified and dropped; only its sha1 is kept. |
| array | no | Optional bounces: work_email, bounce_type, smtp_code, smtp_text, bounced_at. |
| array | no | Optional Account Hiring Watch rows. A closed posting starts a new hire search at that company. |
| object | no | emails, profile_urls, opted_out_emails, opted_out_profile_urls, company_domains, company_names. Suppressed people are dropped before the read and cost nothing. |
| object | no | Optional map of company domain to tier, shown on landed rows. Never blocks a row. |
| object | no | Switches: replacement, closed_posting, contact_data, first_line, icp, include_promotions. Defaults on except include_promotions. |
| string | no | Optional topic phrase for the first line draft, for example: content production at scale. |
| integer | no | Candidates proposed per leaver. A person confirms each. |
| integer | no | Stops the run before a charge that would cross it. |
| integer | no | With state_source actor, a person read within this many days is skipped. |
| integer | no | People read at once. |
| string | no | Optional: signed Standard Webhooks POST of up to 100 signal rows per request. |
| string | no | Signing secret; a whsec_ value is base64 decoded. Your own key, sent as a run input; never stored by the actor. |
Pricing
Pay per event on Apify, billed to your Apify account. Prices in USD.
Event | Free plan | Bronze | Silver | Gold |
| $0.02 | $0.019 | $0.018 | $0.017 |
| $0.068 | $0.0646 | $0.0612 | $0.0578 |
| $0.001 | $0.001 | $0.001 | $0.001 |
Your keys
The actor holds no provider key of its own. Every paid provider key is yours, passed as an input and stored by Apify as a secret input. Without a key, the actor skips that step and says so in the run.
Full actor documentation
apify.com/mambalabs/career-change-signal-engine
License
MIT. See LICENSE.
Available Tools
1 toolwatch_career_changesWatch career changesA
Read a watch list of contacts and return only what changed since the last run: who left, who landed where, who replaced them, and who started after a role closed. Each row carries evidence, a source date, a segment, a first line draft, and Slack, HubSpot, HeyReach, and Instantly payloads. Pass people (required) and, optionally, replies, bounces, posting changes, suppression, and your own provider keys in providerKeys; it never fetches LinkedIn and holds no key of its own. State is kept per watch_list_id. A run that does not succeed is returned as an error with its run ID. Requires an APIFY_TOKEN and consumes Apify credits per call.
| Name | Required | Description | Default |
|---|---|---|---|
| people | Yes | Your watch list, one object per person: person_name, profile_url (optional), company_domain, company_name, title, work_email, relationship (prospect, mgl, deal_contact, customer_champion), external_id, crm_id, deal_id, known_history (a HeyReach copy, a Proofed LinkedIn reader row, or generic roles), last_reading (with state_source caller). The engine reads only these people. At most max_people_per_run per run. | |
| bounces | No | Optional bounces: work_email, bounce_type, smtp_code, smtp_text, bounced_at. | |
| replies | No | Optional reply texts: external_id or work_email or profile_url, text, received_at, channel, is_auto_reply. Text is classified and dropped; only its sha1 is kept. | |
| features | No | Switches: replacement, closed_posting, contact_data, first_line, icp, include_promotions. Defaults on except include_promotions. | |
| icp_tiers | No | Optional map of company domain to tier, shown on landed rows. Never blocks a row. | |
| read_mode | No | stored_first: your known_history first, then your keys. live_only: ignore known_history. stored_only: only known_history, no key calls. | |
| concurrency | No | People read at once. | |
| suppression | No | emails, profile_urls, opted_out_emails, opted_out_profile_urls, company_domains, company_names. Suppressed people are dropped before the read and cost nothing. | |
| webhook_url | No | Optional: signed Standard Webhooks POST of up to 100 signal rows per request. | |
| providerKeys | No | Your own keys: serper or serpapi (web search), prospeo, bounceban (verifier), findymail, exa. Never written to state, output, logs, or the webhook. Your own key, sent as a run input; never stored by the actor. | |
| state_source | No | actor: the engine keeps state between runs in a named store. caller: you send last_reading per person and keep state yourself. | |
| max_spend_usd | No | Stops the run before a charge that would cross it. | |
| watch_list_id | No | Names the list. State is kept per watch list id when state_source is actor. | |
| first_run_mode | No | report: the first run returns every change it finds. baseline: the first run stores state and returns nothing, charging only contact_checked. | |
| sender_context | No | Optional topic phrase for the first line draft, for example: content production at scale. | |
| webhook_secret | No | Signing secret; a whsec_ value is base64 decoded. Your own key, sent as a run input; never stored by the actor. | |
| posting_changes | No | Optional Account Hiring Watch rows. A closed posting starts a new hire search at that company. | |
| max_people_per_run | No | A list longer than this fails the run before any read or charge. Default 150, at most 1,000. | |
| sweep_interval_days | No | With state_source actor, a person read within this many days is skipped. | |
| linkedin_reader_dataset_id | No | Optional: the dataset id of a Proofed LinkedIn reader run on the same Apify account. Rows join to people by profile URL. | |
| max_replacement_candidates | No | Candidates proposed per leaver. A person confirms each. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial context beyond annotations: it never fetches LinkedIn and holds no key of its own, state is kept per watch_list_id, an APIFY_TOKEN is mandatory, and each call consumes Apify credits. This explains why readOnlyHint=false and idempotentHint=false despite the 'Read' framing (state writes, cost), and the error-with-run-ID contract is disclosed. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and output shape are front-loaded in the first two sentences, followed by inputs and operational constraints. Dense and mostly waste-free, though the input enumeration sentence slightly duplicates the schema's own parameter list.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 21-parameter, nested, stateful tool with no output schema, the description covers the essentials: what a row contains (evidence, source date, segment, first-line draft, Slack/HubSpot/HeyReach/Instantly payloads), auth, cost, state persistence, and error behavior. Nothing an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% across all 21 parameters, so the schema already documents every field in depth. The description restates a few of them (people required, replies, bounces, posting changes, suppression, providerKeys) but adds no syntax or format detail beyond the schema. Baseline 3 is correct.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Read a watch list of contacts') plus the precise delta semantics it returns ('who left, who landed where, who replaced them, and who started after a role closed'). No siblings exist, but the purpose is unambiguous without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Makes the required input clear ('Pass people (required)') and names the optional inputs that shape a run (replies, bounces, posting changes, suppression, providerKeys). It explains the failure contract ('A run that does not succeed is returned as an error with its run ID') but gives no explicit when-not or alternative guidance, though no siblings exist to route against.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v0.1.0- First observed
watch_career_changes
TDQS
Scored across 1 tool
With only one tool, there is no possibility of confusion or misselection between overlapping tools. The tool's purpose is singular and clearly stated.
The single tool name watch_career_changes follows a clear snake_case verb_noun pattern. There are no other names to create inconsistency.
One tool is on the thin side for an MCP server, even if the single tool is feature-rich. The rubric marks 1-2 tools as borderline, and this feels slightly under-provisioned.
The tool reads changes from a watch list, but there are no companion tools to create, update, list, or delete watch lists, contacts, suppression rules, or configuration. Agents must manage that lifecycle externally, leaving significant gaps.
Maintenance
Related MCP Connectors
Find companies hiring for a role and geo, qualify them, and watch them for changes.
Live LinkedIn people, company, post and job data, ICP search and job-change signals for AI agents.
Give an AI agent eyes on the web: turn any feed, page, or stream into deduplicated change events.
Delegate standing watches over companies and topics. Get signed webhook alerts. OAuth/API.
Related MCP Servers
- AlicenseAqualityAmaintenanceMonitors a company domain for changes in hiring, tech stack, funding, firmographics, and social presence, returning only the deltas as typed change events.1430 npmMIT
- AlicenseAqualityDmaintenanceTrack competitors, run discovery, read the interpreted change feed, triage items, and pull workspace digests without leaving your AI client.184 npmMIT
- AlicenseAqualityAmaintenanceEnables monitoring named creator watchlists for profile changes, returning only rows that moved since the previous run.1108 npmMIT
- AlicenseNot gradedqualityBmaintenanceJob alerts for AI agents: describe a role once in plain language and get only the new matching postings from 1,500+ tech company and startup job boards (Greenhouse, Lever, Ashby, Workday, Apple, Google, Amazon, Microsoft and more), with salary and experience filters and webhooks. Free, no sign-up.1 npmMIT