Skip to content
Scalekit Docs
Talk to an Engineer Dashboard

Connect AI agents to the Lusha MCP server

Vendor MCP
Open markdown

The Lusha MCP connector routes your AI agent's tool calls to Lusha's own MCP server through Scalekit. Each user connects their own Lusha API key once, and Scalekit sends it with every call, so your agent never handles credentials. It comes with 57 tools.

Tools
57
What they doRead · write · destructive
11 · 42 · 411 read42 write4 destructive
Users sign in with

Setup

  1. Install the SDK

    Terminal window
    npm install @scalekit-sdk/node dotenv
  2. Set your credentials

    Add your Scalekit credentials to your .env file. Find values in app.scalekit.com > Developers > API Credentials.

    .env
    SCALEKIT_ENVIRONMENT_URL=<your-environment-url>
    SCALEKIT_CLIENT_ID=<your-client-id>
    SCALEKIT_CLIENT_SECRET=<your-client-secret>
  3. Create the Lusha MCP connection

    In AgentKit > Connections, create a Lusha MCP connection. The name you give it is the connection_name your code passes. See Configure connections.

    Console steps with screenshots

    Register your Lusha API key with Scalekit so it stores it securely and injects it into every request. Lusha uses API key authentication.

    1. Get your Lusha API key

      • Sign in to Lusha and go to API & connectors → Manage API Keys.
      • Click + Create new Key to generate a new key, or copy the key value from an existing entry.

      Lusha API Hub showing the Manage API Keys tab with an existing key and a Create new Key button

    2. Create a connection in Scalekit

      • In Scalekit dashboard, go to AgentKit → Connections → Create Connection. Find Lusha MCP and click Create.
      • Note the Connection name — you will use this as connection_name in your code (e.g., lushamcp).
      • Click Save.
    3. Add a connected account

      Connected accounts link a specific user identifier in your system to their Lusha API key. Add one in the dashboard to test. In production, each user adds their own through the authorization link: they enter their credentials on the page it opens.

      In the dashboard, to test

      • Open the connection you created and click the Connected Accounts tab → Add account.
      • Fill in:
        • Your User’s ID — a unique identifier for this user in your system (e.g., user_123)
        • API Key — the Lusha API key from step 1
      • Click Create Account.

      From your backend, if your app already has the credentials

      For example, when users enter them on a settings page in your app:

      import { Scalekit, ConnectorStatus } from '@scalekit-sdk/node';
      const scalekit = new Scalekit(
      process.env.SCALEKIT_ENVIRONMENT_URL,
      process.env.SCALEKIT_CLIENT_ID,
      process.env.SCALEKIT_CLIENT_SECRET,
      );
      // Never hard-code credentials — read from secure storage or user input
      const lushaApiKey = getUserLushaApiKey(); // retrieve from your secure store
      const authorizationDetails = {
      details: {
      case: 'staticAuth',
      value: {
      details: {
      api_key: lushaApiKey,
      },
      },
      },
      };
      let { connectedAccount } = await scalekit.actions.upsertConnectedAccount({
      connectionName: 'lushamcp',
      identifier: 'user_123',
      authorizationDetails,
      });
      // Make sure the account is ACTIVE before the first tool call.
      if (connectedAccount?.status !== ConnectorStatus.ACTIVE) {
      ({ connectedAccount } = await scalekit.actions.upsertConnectedAccount({
      connectionName: 'lushamcp',
      identifier: 'user_123',
      authorizationDetails,
      }));
      }
  4. Authorize a user and make your first call

    quickstart.mts
    import { ScalekitClient } from '@scalekit-sdk/node'
    import 'dotenv/config'
    import { createInterface } from 'node:readline/promises'
    const scalekit = new ScalekitClient(
    process.env.SCALEKIT_ENVIRONMENT_URL,
    process.env.SCALEKIT_CLIENT_ID,
    process.env.SCALEKIT_CLIENT_SECRET,
    )
    const actions = scalekit.actions
    const connector = 'lushamcp'
    const identifier = 'user_123'
    // Generate an authorization link for the user
    const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
    console.log('Authorize Lusha MCP:', link)
    const rl = createInterface({ input: process.stdin, output: process.stdout })
    await rl.question('Press Enter after authorizing...')
    rl.close()
    // Make your first call
    const result = await actions.executeTool({
    connector,
    identifier,
    toolName: 'lushamcp_account_usage',
    toolInput: { reason_for_invocation: 'YOUR_REASON_FOR_INVOCATION' },
    })
    console.log(result)
    Terminal window
    npx tsx quickstart.mts

    Each user opens the link once and enters their Lusha MCP server credentials there. If your app already has a user's credentials, add the account from your backend instead, as the console steps above show. See Authorize a user for the full flow and statuses.

Tools

Pass the exact name to execute_tool
Try in PlaygroundRequest a tool
  • lushamcp_account_usageRetrieve account credit balance, rate-limit status, plan info, and per-action credit pricing.Read-only

    Account Usage

    Retrieve account credit balance, rate-limit status, plan info, and per-action credit pricing.

    Inputs

    reason_for_invocationstringrequired
    Brief explanation of why you chose this tool for the current task. Optional audit field; max 500 characters (longer values are truncated). Plain text only.
    conversation_idstring
    Conversation correlation ID. Present only when an earlier tool response in this conversation returned one; that value is carried unchanged on subsequent calls. Omitted on the first call.
  • lushamcp_get_supported_integrationsLusha: returns every CRM Lusha supports (both connected and not), each with its live connection state and export limits.Read-only

    Get Supported Integrations

    Lusha: returns every CRM Lusha supports (both connected and not), each with its live connection state and export limits. Useful as a first step in any connect-or-export flow: it shows whether to connect or go straight to export, and which connection to use when more than one exists. Use when: the user asks which CRMs Lusha supports or integrates with; whether they're connected and to which CRM ("is my Salesforce still connected?", "which CRMs do I have linked?"); or what their export limits are. Also useful before offering or starting any CRM export to determine the connect-vs-export path, and right after a connection completes to confirm state. Do not use when: connecting a CRM (connect_crm); or exporting contacts/companies (use the CRM export tools). Returns ALL supported platforms, not only connected ones — read isAccountConnected / isUserConnected for connection state. Requires an OAuth (user-scoped) session; API-key callers get a 403. Returns: data[]: integrationName, instanceUrl, status, isAccountConnected, isUserConnected, supportedObjects, exportContactLimits, exportCompanyLimits, createdAt, updatedAt. Credits: does not consume credits.

    Inputs

    reason_for_invocationstringrequired
    Brief explanation of why you chose this tool for the current task. Required; at least 20 characters and at most 500 (longer values are truncated). Plain text only.
    conversation_idstring
    Conversation correlation ID: the conversation_id returned by the most recent Lusha tool response in this conversation that included one, passed back unchanged. Calls that carry the same value are linked as one conversation. Absent on the first call of a conversation.
    next_step_refstring
    Next-step reference: the ref of the next step this call carries out, when the user chose it from the next_step_hints of an earlier Lusha tool response, passed back unchanged. Absent otherwise.
  • lushamcp_recommendations_companies_filtersReturn the target ICPs and signal types accepted by recommendations_companys filters.Read-only

    Recommendations Companies Filters

    Return the target ICPs and signal types accepted by recommendations_companys filters. OAuth-only; API key sessions receive a 403.

    Inputs

    reason_for_invocationstringrequired
    Brief explanation of why you chose this tool for the current task. Optional audit field; max 500 characters (longer values are truncated). Plain text only.
    conversation_idstring
    Conversation correlation ID. Present only when an earlier tool response in this conversation returned one; that value is carried unchanged on subsequent calls. Omitted on the first call.
  • lushamcp_recommendations_contacts_filtersReturn the target ICPs and signal types accepted by recommendations_contacts filters.Read-only

    Recommendations Contacts Filters

    Return the target ICPs and signal types accepted by recommendations_contacts filters. OAuth-only; API key sessions receive a 403.

    Inputs

    reason_for_invocationstringrequired
    Brief explanation of why you chose this tool for the current task. Optional audit field; max 500 characters (longer values are truncated). Plain text only.
    conversation_idstring
    Conversation correlation ID. Present only when an earlier tool response in this conversation returned one; that value is carried unchanged on subsequent calls. Omitted on the first call.
  • lushamcp_signals_company_filtersDiscover available company signal types and filter values for signals searches.Read-only

    Signals Company Filters

    Discover available company signal types and filter values for signals searches.

    Inputs

    reason_for_invocationstringrequired
    Brief explanation of why you chose this tool for the current task. Optional audit field; max 500 characters (longer values are truncated). Plain text only.
    conversation_idstring
    Conversation correlation ID. Present only when an earlier tool response in this conversation returned one; that value is carried unchanged on subsequent calls. Omitted on the first call.
    filterTypestring
    Optional. Omit to discover signal types and the directory of available filter types. Set to fetch values for a single filter (e.g., 'newsEventTypes', 'hiringByDepartments', 'hiringByLocations', 'intentCategories', 'intentTopics'). 'intentTopics' searches the full intent topic catalog by name (literal substring) and returns up to 50 { topic, category, description } matches, best match first, plus 'total' and 'truncated' (true means more matched; narrow the query), for filters.include.intentTopics.one of newsEventTypeshiringByDepartmentshiringByLocationsintentCategoriesintentTopics
    querystring
    Search text. Required when filterType is 'hiringByLocations' or 'intentTopics' (neither is enumerable; intentTopics needs at least 2 letters or digits). Not supported for other filterTypes or when filterType is omitted.
  • lushamcp_signals_contact_filtersReturn available contact signal types accepted by contacts signals tools.Read-only

    Signals Contact Filters

    Return available contact signal types accepted by contacts signals tools.

    Inputs

    reason_for_invocationstringrequired
    Brief explanation of why you chose this tool for the current task. Optional audit field; max 500 characters (longer values are truncated). Plain text only.
    conversation_idstring
    Conversation correlation ID. Present only when an earlier tool response in this conversation returned one; that value is carried unchanged on subsequent calls. Omitted on the first call.
  • lushamcp_table_get_entitiesRead a page of a Workspace table's rows, including populated column values.Read-only

    Table Get Entities

    Read a page of a Workspace table's rows, including populated column values.

    Inputs

    entity_typestringrequired
    Which Lusha entity the table holds: 'contacts' or 'companies'. Routes the call to /v3/contacts/* or /v3/companies/*; a table only ever holds one entity type.one of contactscompanies
    reason_for_invocationstringrequired
    Brief explanation of why you chose this tool for the current task. Optional audit field; max 500 characters (longer values are truncated). Plain text only.
    table_idstringrequired
    The target Workspace table's UUID, as returned by table_create or table_list.
    conversation_idstring
    Conversation correlation ID. Present only when an earlier tool response in this conversation returned one; that value is carried unchanged on subsequent calls. Omitted on the first call.
    emailstring
    Owner email: the user in the account that owns the table (the API resolves it to a userId). Needed only when the credential has no associated user, such as an API key that does not resolve to a specific user. With OAuth, or an API key already scoped to a user, the caller's own userId identifies the owner and email can be omitted; it may still be passed to act on behalf of another owner.
    pageinteger
    Page number (0-based, max 100).
    page_sizeinteger
    Items per page (1-100, default 100). Also sets how many credits are reserved before the read: the full page size, not the rows returned.
  • lushamcp_table_listList the caller's Workspace contacts or companies tables with pagination and name/status filters.Read-only

    Table List

    List the caller's Workspace contacts or companies tables with pagination and name/status filters.

    Inputs

    entity_typestringrequired
    Which Lusha entity the table holds: 'contacts' or 'companies'. Routes the call to /v3/contacts/* or /v3/companies/*; a table only ever holds one entity type.one of contactscompanies
    reason_for_invocationstringrequired
    Brief explanation of why you chose this tool for the current task. Optional audit field; max 500 characters (longer values are truncated). Plain text only.
    conversation_idstring
    Conversation correlation ID. Present only when an earlier tool response in this conversation returned one; that value is carried unchanged on subsequent calls. Omitted on the first call.
    emailstring
    Filter to tables owned by this email. REQUIRED when authenticating with an API key (there is no signed-in user to default to); with OAuth the caller is identified by the token, so it is optional and defaults to the caller.
    namestring
    Filter by name (substring match).
    pageinteger
    Page number (0-based, max 100).
    page_sizeinteger
    Items per page (1-100, default 100).
    statusstring
    Filter tables by lifecycle status.one of activearchiveddeleted