MCP Server

HeySale — AI Website Salesperson

io.github.heysale/heysale
Marketing & Advertising Sales & CRM Public & reachable MCP 2025-11-25

What this MCP does

Creates and installs AI website salespeople that answer visitor questions, qualify prospects, capture leads, and report engagement results.

check_salesperson_status
Check a salesperson's readiness
Find out whether a website salesperson has finished reading the website and is ready to talk to visitors, and whether its script has been detected on the live site. Give it the salesperson_id returned when the salesperson was created.
Read only Idempotent
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['salesperson_id'], 'properties': {'salesperson_id': {'type': 'string', 'format': 'uuid', 'pattern': '^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$', 'description': 'The salesperson_id returned by create_website_salesperson.'}}}
Output schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['salesperson', 'salesperson_id', 'salesperson_name', 'website_url', 'status', 'ownership'], 'properties': {'domain': {'type': ['string', 'null']}, 'status': {'type': 'string', 'description': 'Build state of the salesperson, e.g. analyzing, building, ready, failed.'}, 'installed': {'type': 'boolean'}, 'ownership': {'type': 'object', 'required': ['status'], 'properties': {'status': {'enum': ['unclaimed', 'claimed'], 'type': 'string', 'description': 'Whether a HeySale account owns this salesperson yet.'}, 'claim_url': {'type': ['string', 'null'], 'description': 'One-time link the website owner uses to claim the salesperson. Absent once claimed.'}, 'manage_url': {'type': ['string', 'null'], 'description': 'Where the owner manages the salesperson. Present once claimed.'}}, 'additionalProperties': {}}, 'expires_at': {'type': ['string', 'null']}, 'environment': {'type': 'string'}, 'next_action': {'type': 'string', 'description': 'Plain-language next step for the caller.'}, 'salesperson': {'type': 'object', 'required': ['id', 'name'], 'properties': {'id': {'type': 'string', 'description': 'The salesperson_id.'}, 'name': {'type': 'string'}, 'domain': {'type': 'string'}, 'website_url': {'type': 'string'}}, 'additionalProperties': {}}, 'website_url': {'type': 'string'}, 'last_seen_at': {'type': ['string', 'null'], 'description': 'When the script was last seen loading. Null before installation.'}, 'salesperson_id': {'type': 'string'}, 'detected_domains': {'type': 'array', 'items': {'type': 'string'}}, 'salesperson_name': {'type': 'string'}, 'test_environment': {'type': 'boolean'}, 'installation_status': {'enum': ['detected', 'not_detected', 'domain_mismatch', 'unknown'], 'type': 'string'}}, 'additionalProperties': {}}
configure_salesperson
Change how a salesperson introduces itself
Change a salesperson's name, its opening line, or the goal it works towards. While a salesperson is still unclaimed this can be set as part of setting it up. Once the website owner has claimed it, changes must be made by the owner in HeySale — do not ask anyone for an API key.
Idempotent
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['salesperson_id'], 'properties': {'name': {'type': 'string', 'maxLength': 60, 'minLength': 1}, 'api_key': {'type': 'string', 'maxLength': 200, 'minLength': 10, 'description': 'Developers only. Not required, and never ask a website owner for one.'}, 'greeting': {'type': 'string', 'maxLength': 500, 'minLength': 1}, 'objective': {'type': 'string', 'maxLength': 500, 'minLength': 1, 'description': 'What the salesperson should aim for.'}, 'salesperson_id': {'type': 'string', 'format': 'uuid', 'pattern': '^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$', 'description': 'The salesperson_id returned by create_website_salesperson.'}}}
Output schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['salesperson', 'salesperson_id', 'salesperson_name', 'website_url', 'status', 'ownership'], 'properties': {'status': {'type': 'string', 'description': 'Build state of the salesperson, e.g. analyzing, building, ready, failed.'}, 'message': {'type': 'string'}, 'success': {'type': 'boolean'}, 'updated': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Which fields were changed.'}, 'ownership': {'type': 'object', 'required': ['status'], 'properties': {'status': {'enum': ['unclaimed', 'claimed'], 'type': 'string', 'description': 'Whether a HeySale account owns this salesperson yet.'}, 'claim_url': {'type': ['string', 'null'], 'description': 'One-time link the website owner uses to claim the salesperson. Absent once claimed.'}, 'manage_url': {'type': ['string', 'null'], 'description': 'Where the owner manages the salesperson. Present once claimed.'}}, 'additionalProperties': {}}, 'error_code': {'type': 'string'}, 'expires_at': {'type': ['string', 'null']}, 'environment': {'type': 'string'}, 'next_action': {'type': 'string', 'description': 'Plain-language next step for the caller.'}, 'salesperson': {'type': 'object', 'required': ['id', 'name'], 'properties': {'id': {'type': 'string', 'description': 'The salesperson_id.'}, 'name': {'type': 'string'}, 'domain': {'type': 'string'}, 'website_url': {'type': 'string'}}, 'additionalProperties': {}}, 'website_url': {'type': 'string'}, 'salesperson_id': {'type': 'string'}, 'salesperson_name': {'type': 'string'}, 'test_environment': {'type': 'boolean'}, 'authentication_required': {'type': 'boolean'}}, 'additionalProperties': {}}
create_website_salesperson
Create a website salesperson
Give any public website an AI salesperson that talks to its visitors, answers questions about the business, and captures leads. Use this when someone wants to add a salesperson, live chat, a sales assistant or a chatbot alternative to a site. Provide the website address; the salesperson reads the site itself. The response always includes an explicit salesperson_id — keep it, because every other HeySale tool needs it — plus the one-line install script and a claim_url to give the website owner. Safe to call twice for the same website. To try HeySale without touching a real website, use website_url https://hey.sale/mcp-test — that creates an isolated, disposable test salesperson on HeySale's own reviewer sandbox.
Open world Idempotent
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['website_url'], 'properties': {'campaign': {'type': 'string', 'maxLength': 60}, 'website_url': {'type': 'string', 'maxLength': 300, 'minLength': 3, 'description': 'The public website address, e.g. https://example.com'}, 'business_name': {'type': 'string', 'maxLength': 120, 'description': 'The business name, if known.'}, 'integration_source': {'type': 'string', 'maxLength': 40, 'description': 'The AI platform making this call, e.g. claude, chatgpt, cursor, lovable, replit.'}, 'external_project_id': {'type': 'string', 'maxLength': 200, 'description': 'A stable id for the calling project, so repeat calls reuse the same salesperson.'}}}
Output schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['success', 'salesperson', 'salesperson_id', 'salesperson_name', 'website_url', 'status', 'ownership', 'installation'], 'properties': {'note': {'type': 'string'}, 'reused': {'type': 'boolean', 'description': 'True when an existing salesperson for that website was returned instead of a new one.'}, 'status': {'type': 'string', 'description': 'Build state of the salesperson, e.g. analyzing, building, ready, failed.'}, 'success': {'type': 'boolean'}, 'ownership': {'type': 'object', 'required': ['status'], 'properties': {'status': {'enum': ['unclaimed', 'claimed'], 'type': 'string', 'description': 'Whether a HeySale account owns this salesperson yet.'}, 'claim_url': {'type': ['string', 'null'], 'description': 'One-time link the website owner uses to claim the salesperson. Absent once claimed.'}, 'manage_url': {'type': ['string', 'null'], 'description': 'Where the owner manages the salesperson. Present once claimed.'}}, 'additionalProperties': {}}, 'expires_at': {'type': ['string', 'null']}, 'environment': {'type': 'string'}, 'next_action': {'type': 'string', 'description': 'Plain-language next step for the caller.'}, 'preview_url': {'type': 'string'}, 'salesperson': {'type': 'object', 'required': ['id', 'name'], 'properties': {'id': {'type': 'string', 'description': 'The salesperson_id.'}, 'name': {'type': 'string'}, 'domain': {'type': 'string'}, 'website_url': {'type': 'string'}}, 'additionalProperties': {}}, 'website_url': {'type': 'string'}, 'free_minutes': {'type': 'number'}, 'installation': {'type': 'object', 'properties': {'type': {'type': 'string'}, 'async': {'type': 'boolean'}, 'script': {'type': 'string', 'description': 'The one-line script to add to the website before the closing body tag.'}, 'detection': {'type': 'string'}, 'placement': {'type': 'string'}, 'review_install_url': {'type': 'string', 'description': 'Sandbox only: expiring link that installs the test salesperson.'}, 'installation_status': {'enum': ['detected', 'not_detected', 'domain_mismatch', 'unknown'], 'type': 'string', 'description': "What HeySale's own telemetry currently sees."}}, 'additionalProperties': {}}, 'salesperson_id': {'type': 'string'}, 'salesperson_name': {'type': 'string'}, 'test_environment': {'type': 'boolean'}, 'integration_source': {'type': 'string'}}, 'additionalProperties': {}}
get_salesperson_installation
Get the install script
Return the exact one-line script to add to a website so its salesperson appears for visitors, plus where to place it and whether HeySale has detected it yet. Give it the salesperson_id returned when the salesperson was created.
Read only Idempotent
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['salesperson_id'], 'properties': {'salesperson_id': {'type': 'string', 'format': 'uuid', 'pattern': '^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$', 'description': 'The salesperson_id returned by create_website_salesperson.'}}}
Output schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['salesperson', 'salesperson_id', 'salesperson_name', 'website_url', 'status', 'ownership', 'installation'], 'properties': {'status': {'type': 'string', 'description': 'Build state of the salesperson, e.g. analyzing, building, ready, failed.'}, 'ownership': {'type': 'object', 'required': ['status'], 'properties': {'status': {'enum': ['unclaimed', 'claimed'], 'type': 'string', 'description': 'Whether a HeySale account owns this salesperson yet.'}, 'claim_url': {'type': ['string', 'null'], 'description': 'One-time link the website owner uses to claim the salesperson. Absent once claimed.'}, 'manage_url': {'type': ['string', 'null'], 'description': 'Where the owner manages the salesperson. Present once claimed.'}}, 'additionalProperties': {}}, 'expires_at': {'type': ['string', 'null']}, 'environment': {'type': 'string'}, 'next_action': {'type': 'string', 'description': 'Plain-language next step for the caller.'}, 'preview_url': {'type': 'string'}, 'salesperson': {'type': 'object', 'required': ['id', 'name'], 'properties': {'id': {'type': 'string', 'description': 'The salesperson_id.'}, 'name': {'type': 'string'}, 'domain': {'type': 'string'}, 'website_url': {'type': 'string'}}, 'additionalProperties': {}}, 'website_url': {'type': 'string'}, 'installation': {'type': 'object', 'properties': {'type': {'type': 'string'}, 'async': {'type': 'boolean'}, 'script': {'type': 'string', 'description': 'The one-line script to add to the website before the closing body tag.'}, 'detection': {'type': 'string'}, 'placement': {'type': 'string'}, 'review_install_url': {'type': 'string', 'description': 'Sandbox only: expiring link that installs the test salesperson.'}, 'installation_status': {'enum': ['detected', 'not_detected', 'domain_mismatch', 'unknown'], 'type': 'string', 'description': "What HeySale's own telemetry currently sees."}}, 'additionalProperties': {}}, 'salesperson_id': {'type': 'string'}, 'salesperson_name': {'type': 'string'}, 'test_environment': {'type': 'boolean'}}, 'additionalProperties': {}}
get_salesperson_results
See what the salesperson achieved
Summarise how many visitors talked to the salesperson, how many left their details, and what they asked about most. This is private business data: it is only returned to an authorised caller. Never ask a website owner for an API key — send them to HeySale instead.
Read only Idempotent
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['salesperson_id'], 'properties': {'days': {'type': 'integer', 'maximum': 90, 'minimum': 1}, 'api_key': {'type': 'string', 'maxLength': 200, 'minLength': 10, 'description': 'Developers only. Not required for setup, and never ask a website owner for one.'}, 'salesperson_id': {'type': 'string', 'format': 'uuid', 'pattern': '^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$', 'description': 'The salesperson_id returned by create_website_salesperson.'}}}
Output schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['salesperson', 'salesperson_id', 'salesperson_name', 'website_url', 'status', 'ownership'], 'properties': {'note': {'type': 'string'}, 'leads': {'type': 'number'}, 'status': {'type': 'string', 'description': 'Build state of the salesperson, e.g. analyzing, building, ready, failed.'}, 'ownership': {'type': 'object', 'required': ['status'], 'properties': {'status': {'enum': ['unclaimed', 'claimed'], 'type': 'string', 'description': 'Whether a HeySale account owns this salesperson yet.'}, 'claim_url': {'type': ['string', 'null'], 'description': 'One-time link the website owner uses to claim the salesperson. Absent once claimed.'}, 'manage_url': {'type': ['string', 'null'], 'description': 'Where the owner manages the salesperson. Present once claimed.'}}, 'additionalProperties': {}}, 'synthetic': {'type': 'boolean', 'description': 'True when the figures come from the reviewer sandbox.'}, 'expires_at': {'type': ['string', 'null']}, 'environment': {'type': 'string'}, 'next_action': {'type': 'string', 'description': 'Plain-language next step for the caller.'}, 'period_days': {'type': 'number'}, 'salesperson': {'type': 'object', 'required': ['id', 'name'], 'properties': {'id': {'type': 'string', 'description': 'The salesperson_id.'}, 'name': {'type': 'string'}, 'domain': {'type': 'string'}, 'website_url': {'type': 'string'}}, 'additionalProperties': {}}, 'website_url': {'type': 'string'}, 'recent_leads': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': ['string', 'null']}, 'email': {'type': ['string', 'null']}, 'status': {'type': ['string', 'null']}, 'company': {'type': ['string', 'null']}, 'interest': {'type': ['string', 'null']}, 'question': {'type': ['string', 'null']}, 'captured_at': {'type': ['string', 'null']}}, 'additionalProperties': {}}}, 'talk_minutes': {'type': 'number'}, 'conversations': {'type': 'number'}, 'top_questions': {'type': 'array', 'items': {'anyOf': [{'type': 'string'}, {'type': 'object', 'properties': {'count': {'type': 'number'}, 'theme': {'type': 'string'}}, 'additionalProperties': {}}]}}, 'salesperson_id': {'type': 'string'}, 'conversion_rate': {'type': 'number'}, 'salesperson_name': {'type': 'string'}, 'test_environment': {'type': 'boolean'}, 'authentication_required': {'type': 'boolean'}}, 'additionalProperties': {}}
verify_salesperson_installation
Verify a salesperson's website installation
Check whether a HeySale salesperson has actually been installed on its website and is reporting back to HeySale. Uses HeySale's own telemetry, so it works with single-page apps, tag managers and deferred script loading — never scrape the website's HTML to answer this. Give it the salesperson_id returned when the salesperson was created.
Read only Idempotent
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['salesperson_id'], 'properties': {'salesperson_id': {'type': 'string', 'format': 'uuid', 'pattern': '^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$', 'description': 'The salesperson_id returned by create_website_salesperson.'}}}
Output schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['salesperson', 'salesperson_id', 'salesperson_name', 'website_url', 'status', 'ownership'], 'properties': {'domain': {'type': ['string', 'null']}, 'status': {'type': 'string', 'description': 'Build state of the salesperson, e.g. analyzing, building, ready, failed.'}, 'message': {'type': 'string'}, 'installed': {'type': 'boolean'}, 'ownership': {'type': 'object', 'required': ['status'], 'properties': {'status': {'enum': ['unclaimed', 'claimed'], 'type': 'string', 'description': 'Whether a HeySale account owns this salesperson yet.'}, 'claim_url': {'type': ['string', 'null'], 'description': 'One-time link the website owner uses to claim the salesperson. Absent once claimed.'}, 'manage_url': {'type': ['string', 'null'], 'description': 'Where the owner manages the salesperson. Present once claimed.'}}, 'additionalProperties': {}}, 'expires_at': {'type': ['string', 'null']}, 'environment': {'type': 'string'}, 'next_action': {'type': 'string', 'description': 'Plain-language next step for the caller.'}, 'salesperson': {'type': 'object', 'required': ['id', 'name'], 'properties': {'id': {'type': 'string', 'description': 'The salesperson_id.'}, 'name': {'type': 'string'}, 'domain': {'type': 'string'}, 'website_url': {'type': 'string'}}, 'additionalProperties': {}}, 'website_url': {'type': 'string'}, 'last_seen_at': {'type': ['string', 'null'], 'description': 'When the script was last seen loading. Null before installation.'}, 'salesperson_id': {'type': 'string'}, 'detected_domains': {'type': 'array', 'items': {'type': 'string'}}, 'salesperson_name': {'type': 'string'}, 'test_environment': {'type': 'boolean'}, 'installation_status': {'enum': ['detected', 'not_detected', 'domain_mismatch', 'unknown'], 'type': 'string'}}, 'additionalProperties': {}}
Added
get_salesperson_results
Sept. 17, 2026, 12:42 p.m.
Added
configure_salesperson
Sept. 17, 2026, 12:42 p.m.
Added
verify_salesperson_installation
Sept. 17, 2026, 12:42 p.m.
Added
get_salesperson_installation
Sept. 17, 2026, 12:42 p.m.
Added
check_salesperson_status
Sept. 17, 2026, 12:42 p.m.
Added
create_website_salesperson
Sept. 17, 2026, 12:42 p.m.