Skip to main content
Glama

Max MCP Server (Digital Crew)

MCP server for Max, the AI sales agent from Digital Crew. Max is built for lead qualification, cold outreach, and pipeline growth—see the product story on max.digitalcrew.tech.

This repo hosts a Next.js app that exposes MCP tools over Streamable HTTP so Max (or any MCP-capable client) can read and update workspace profile settings against the Digital Crew backend API.

What it does

The server registers MCP tools that proxy to the Digital Crew max-agent API.

Generated by pnpm docs:tools — do not edit by hand.

154 tools registered.

Tool

Purpose

add_prospects_to_list

Add prospects to a prospect list by their UUIDs.

agent_draft_create

Stage an action (e.g. send a nudge, upsert a CRM contact, export a CSV) as a PENDING draft in the workspace for the human to approve. The draft is persisted in max-agent's agent_action_drafts table; nothing runs until the human approves. Returns { draft_id, state:'pending', review_url }. AFTER CREATING, POST THE RETURNED review_url (or a link to the agent drafts view in the workspace UI) TO THE USER'S CHAT CHANNEL SO THEY CAN APPROVE. Use this whenever an agent wants to take a write action on the user's behalf but the user hasn't pre-authorized the specific instance.

agent_draft_get

Fetch one agent action draft by id, including its full payload, current state, audit trail, and any execution result. Use to inspect a specific draft before recommending approve/reject to the user.

agent_draft_list

List agent action drafts in the workspace, optionally filtered by state (pending/approved/rejected/executed/failed/canceled) and/or action_type. Paginated via { limit, cursor }. Returns { data: [...], next_cursor? }. Use to show the user what's awaiting their approval or to audit recently-executed actions.

apollo_add_more

Append more leads to an existing Apollo list (async). Re-runs the saved search for additional results.

apollo_create_list

Create an Apollo-backed prospect list (async). Starts people search → ingestion. Poll the list status (or use wait_for_prospect_list) for progress. Auto-generates an idempotency_key if not provided so retries are safe.

approve_inbox_draft

Approve a drafted reply and send it in-thread via Unipile, setting the action's status to 'approved'. Optionally pass body to send an edited reply instead of the stored draft. Returns the updated {data: InboxAutopilotAction}. Fails with 404 (draft not found), 409 (action not in 'draft' status), or 400 SendReplyError (code CHAT_NOT_FOUND | ACCOUNT_NOT_FOUND | ACCOUNT_NOT_CONNECTED | NO_PROSPECT_EMAIL | SEND_FAILED).

approve_proposal

Approve a pending proposal and launch its draft campaign. SYNCHRONOUS — max-agent builds the prospect list, creates the campaign, and launches it (may take a while). Optionally pass modifications (titles, target_prospect_ids, campaign_name, campaign_description) to override the recommendation before launch; omit them to approve as-is. On success returns {data: SignalProposal (status 'launched', draft_campaign_id set), campaign_id}. Can fail with 402 (enrichment quota exceeded — proposal reverts to pending), 409 (not pending / already decided / expired), or 422 (no target prospects / no connected account).

archive_campaign

Archive a campaign (soft delete) — hidden from default views but restorable.

archive_chat

Archive a chat (soft delete). Messages remain, use archived=true filter to see them.

book_meeting

Create a Cal.com booking and record it as a meeting. event_type_id defaults to the connection's default event type; start is a required ISO8601 UTC time; attendee_name, attendee_email, and attendee_time_zone (IANA) describe the attendee. Optionally pass prospect_id (advances that prospect to 'replied'), campaign_id, and a flat string metadata map. Returns the created {data: meeting row} (calcom_booking_uid, meeting_url, status 'scheduled', etc.). Fails with 409 (no calendar connected), 400 (invalid body / no default event type), or 4xx/502 CALCOM_ERROR (e.g. slot conflict / instance unreachable).

bulk_delete_organizations

Delete multiple organizations. Set deleteProspects=true to cascade-delete linked prospects.

bulk_delete_prospects

Delete multiple prospects by IDs.

bulk_enrich

Queue many prospects and/or organizations for background enrichment by the cron worker (does NOT run inline). Provide prospect_ids and/or organization_ids. Returns {accepted} — how many rows were queued. Use this instead of calling enrich_prospect in a loop when enriching more than a couple of records.

bulk_import_organizations

Import multiple organizations. Deduplicates by domain. Returns imported/existing/failed counts.

bulk_import_prospects

Import multiple prospects at once. Deduplicates by email. Returns imported/existing/failed counts.

calendar_status

Return the workspace's Cal.com connection status. Returns {data: {connected: false}} when no instance is connected, or {data: CalendarStatus} (baseUrl, username, label, defaultEventTypeId, eventTypes) when connected. eventTypes may be [] if the instance is currently unreachable. The api_key is never returned.

cancel_meeting

Cancel a recorded meeting by its meetings.id UUID. If the meeting has a Cal.com booking uid it is cancelled on Cal.com first, then the row is marked cancelled. Optionally pass a reason. Returns the updated {data: meeting row} with status 'cancelled'. Fails with 404 (unknown / not in this workspace), 409 (no calendar connected, only when a Cal.com cancel is needed), or 4xx/502 CALCOM_ERROR.

claire_deep_research

Multi-source background research on a named person or company. Returns recent activity, news, role context, company highlights, and proof points. Synchronous (may take 30-90s). Call this BEFORE crafting personalized outreach so the message reflects who the prospect actually is.

claire_extract_prospects_from_url

Fetch a public URL (conference attendee list, team / about page, press release, panel announcement, etc.) and extract structured prospects (people / contacts) from it via Claire. Returns { prospects:[{ name, title, company, linkedin_url?, email?, ... }], source_url, extracted_count, claire_request_id? }. Use when the user pastes a URL and asks to 'find leads here' / 'build a list from this page'. Pair with create_prospect or import_prospect_list_csv to persist the result.

claire_find_competitors

Identify direct competitors of a company by URL. Returns a list of competing companies with descriptions and sources. Synchronous (typically 1-3 min). Use to expand a prospect list with similar companies or to ground competitive positioning in outreach.

claire_market_watch

Run a market-watch pass on a URL, optionally filtered by criteria (e.g. 'pricing', 'hiring', 'funding'). Returns a snapshot of detected signals. Use to inform outreach timing (e.g. just-funded companies) or to spot competitive moves.

claire_search

Free-text research query against Claire's hub. Use for quick lookups like industry trends, funding news, or any topic where you'd otherwise google. Synchronous — waits for Claire to finish and returns the result. Use mode='lite' for fast first-pass (default), 'full' for deeper multi-source.

clear_failed_requests

Drain the dead-letter queue. Returns the number of entries removed. Use after manually replaying or after resolving the upstream issue.

connect_calendar

Connect the workspace's self-hosted Cal.com instance so Max can read availability and book meetings. Validates the credentials by calling Cal.com listEventTypes before storing them. Pass base_url (the instance API base, e.g. https://cal.example.com or .../api/v2), api_key, and optionally default_event_type_id. Returns {data: CalendarStatus} with connected:true, baseUrl, username, label, defaultEventTypeId, and the list of eventTypes. The api_key is never returned.

create_campaign

Create a new campaign in draft state. Requires name, included_lists, and accounts. Won't send until launched.

create_intent_trigger

Set up a trigger that watches a target URL for a buying signal (funding, hiring, tech_stack, news, job_change, or custom). Optionally scope it to an organization or prospect and set how often it re-polls. Returns the created {data: IntentTrigger}. Used to start monitoring for intent before any signals exist.

create_organization

Create a new organization/company record.

create_prospect

Create a single prospect. Deduplicates by email — returns existing row if email already exists.

create_prospect_list

Create an empty platform prospect list. For Apollo-sourced lists, use apollo_create_list instead.

crm_assign_prospects

Assign prospects to HubSpot owners using agent_settings.assignment_rules (or assignment_rules_override). First matching rule wins; no match → owner_id null, reason 'no rule matched', priority 'low'. Priority otherwise derives from prospect.score (>=75 high, 50–74 med, <50 low) else 'med'. Returns { assignments: [{ id|email, owner_id, owner_name, owner_email, reasoning, priority }] }.

crm_detect_forecast_changes

Compare current open HubSpot deals against the workspace's deal snapshot from window_days ago (read from max-agent's crm_deal_snapshots via GET /api/v1/crm/deal-snapshots). Flags amount changes (abs delta pct > threshold), stage moves (forward/backward via pipeline displayOrder), close-date slips (> threshold days), new deals since last snapshot, and deals that disappeared. Returns { window_days, baseline_iso, current_iso, changes:[{ deal_id, dealname, owner_id, owner_name, amount, prior_amount, amount_delta_pct, stage, prior_stage, stage_movement, close_date, prior_close_date, close_date_slip_days, flag_reasons[] }] }.

crm_export_import_csv

Build a HubSpot-import CSV (base64-encoded) from prospects. When dedup_against_hubspot (default true), drops prospects whose email already exists in HubSpot (concurrency <=5). Columns: Email, First Name, Last Name, Job Title, Company, Company Domain, Country, Industry, Number of Employees [, HubSpot Owner ID when include_assignment]. Returns { csv_base64, row_count, deduped_count, deduped:[{ email, existing_id }] }.

crm_get_contact

Fetch a single CRM contact by email (the dedup identity). Returns null if not found.

crm_get_deal

Fetch a single HubSpot deal by id, including its full properties and associated company/contact ids. Returns null if not found.

crm_list_activities

List HubSpot engagements (call/email/meeting/note/task) with optional filters (deal, contact, owner, types, since). Per-type queries are merged sorted by timestamp desc. Returns id, type, timestamp, ownerId, dealId, contactId, subject, body.

crm_list_deals

List deals from HubSpot with optional filters (stage, owner, pipeline, amount range, close-date range, modified-after). Returns id, dealname, amount, ownerId, stage, pipeline, closeDate, lastModified, lastActivityDate, nextStep, associated company/contact ids.

crm_list_owners

List HubSpot owners (sales reps) for the workspace. Returns id, email, firstName, lastName, teams. Use to map deals/assignments to people.

crm_list_pipeline_stages

List deal pipeline stages (optionally scoped to one pipeline). Returns id, label, displayOrder, pipelineId, isWonStage, isLostStage.

crm_pipeline_risk_scan

Scan open HubSpot deals for risk: days inactive, days-to-close, missing fields (amount/owner/next_step/last_activity), close-date slipping, and high-value-low-activity. Computes a transparent weighted risk_score (0–100) and a PRIVATE suggested nudge draft to the owner (never sent). Uses agent_settings.risk_thresholds. Returns { scanned_count, flagged:[...] }.

crm_score_prospects

Score prospects 0–100 against the workspace ICP rules (agent_settings.icp_rules): country 25, industry 25, employee-in-range 20, any title keyword 30. With no rules configured, every prospect scores 50 (reason no_icp_rules_configured). Returns { scored: [{ id|email, score, matched[], missed[] }] }.

crm_search_contacts

Search the connected CRM (HubSpot) for contacts by free text (name, email, company). Returns matching contacts. Use before creating a contact to check if one already exists.

crm_status

Report whether HubSpot is connected for this workspace. Attempts a cheap HubSpot read; returns { connected: bool, ... }.

crm_upsert_company

Create-or-update a company in the connected CRM, matched by domain — never creates a duplicate. Requires a read + write HubSpot connection.

crm_upsert_contact

Create-or-update a contact in the connected CRM, matched by email — never creates a duplicate. Use when the user asks to add or update a contact in HubSpot. Requires a read + write HubSpot connection.

crm_weekly_brief_compose

Compose a structured weekly sales brief from last week's activities, current open deals, the pipeline risk scan, and per-rep aggregates. Pure data (no writes). Returns { week_ending, last_week_summary, this_week_priorities, stale_deals, deals_without_next_step, top_risks, per_rep_questions, suggested_bj_notes, action_items }. Pass the result to notion_publish_weekly_brief to draft it in Notion.

delete_campaign

Permanently delete a campaign and all its workflow executions. Prefer archive for soft removal.

delete_organization

Delete an organization. Linked prospects get organization_id = null.

delete_prospect

Delete a prospect permanently.

delete_prospect_list

Delete a prospect list (prospects themselves are NOT deleted).

disable_trigger

Disable an intent trigger (sets active=false) so it stops re-polling. Returns the updated {data: IntentTrigger}, or a 404 error if the trigger is not in this workspace.

disconnect_account

Disconnect a LinkedIn or email account from the workspace. Use hosted_auth_link to reconnect.

enrich_organization

Run Claire deep-research on an organization and save the result onto the record. SYNCHRONOUS — waits for Claire (may take 30-180s) and returns {status} ('complete' with the research, 'skipped' if the org has no name, or 'busy' if another enrichment is already running). Counts against the workspace's daily enrichment quota; returns a 429 quota error when exhausted. Set force=true to re-enrich an already-complete record.

enrich_prospect

Run Claire deep-research on a prospect and save the result onto the record. SYNCHRONOUS — waits for Claire (may take 30-180s) and returns {status} ('complete' with the research, 'skipped' if the prospect has no name, or 'busy' if another enrichment is already running). Counts against the workspace's daily enrichment quota; returns a 429 quota error when exhausted. Set force=true to re-enrich an already-complete record. Call this BEFORE crafting personalized outreach.

explorium_add_more

Append more leads to an existing Explorium list (async). Re-runs the saved search for additional results. Poll the list (or use wait_for_prospect_list) for progress.

explorium_create_company_list

Create an Explorium-backed company (organization) list (async). Runs a business search with the given filters → enrichment → ingestion. Returns a pending list DTO; poll its status (or use wait_for_prospect_list) until completed. Auto-generates an idempotency_key if not provided so retries are safe.

explorium_create_list

Create an Explorium-backed prospect (people) list (async). Runs a people search with the given filters → enrichment → ingestion. Returns a pending list DTO; poll its status (or use wait_for_prospect_list) until completed. Auto-generates an idempotency_key if not provided so retries are safe.

generate_message_preview

Use AI to generate a personalized message for a prospect. Charges credits. Specify channel and prompt.

generate_workflow

Use AI to generate a campaign workflow from natural language. Charges credits. Provide a prompt or structured fields.

get_account

Get full details of a connected account — provider, channel, config, sync status.

get_account_rate_limits

Get daily/weekly sending limits and current usage for a specific account.

get_availability

Fetch open booking slots for an event type, grouped by date. event_type_id defaults to the connection's default event type; start defaults to now and end to now + 14 days; time_zone is an optional IANA string to localize slots. Returns {data: {eventTypeId, slotsByDate: {: [{start, end?}]}}}. Fails with 409 if no calendar is connected, or 400 if no event type id is available.

get_campaign

Get full details of a campaign by ID — workflow, scheduling, accounts, prospect lists, stats.

get_campaign_engagement_summary

Engagement summary for a campaign: open/click/reply/bounce rates plus per-link click detail (top links, distinct URLs clicked).

get_campaign_lead_analytics

Per-prospect breakdown — where each lead is in the workflow and message event history.

get_campaign_memory

Read Max's durable memory for a campaign (ICP, decisions, notes). Recall this when working on one of several simultaneous campaigns so you keep them straight.

get_campaign_node_run_counts

Map of workflow node ID → execution count. Useful for funnel visualization.

get_campaign_stats

Aggregate performance stats — email open/reply rates, LinkedIn connection/reply rates, execution counts.

get_chat

Get full details of a single Unibox chat/conversation thread.

get_circuit_status

Inspect the circuit-breaker state for each upstream host the MCP server has called. Shows whether requests are being fast-failed (state=open), probing (half-open), or flowing normally (closed).

get_dashboard_kpis

Workspace-wide aggregate stats — execution counts, email/LinkedIn rates, completion percentage.

get_email_tracking_events

Raw per-event email tracking rows for a prospect (opens, clicks, replies, bounces) with url/ip/user_agent detail. Newest first. Optionally filter by event_types.

get_enrichment_credits

Return the workspace's daily enrichment quota usage: {cap, used_today, remaining}. Check this before a large bulk enrichment to confirm there's headroom.

get_enrichment_status

Check the enrichment state of a single prospect or organization. Provide exactly one of prospect_id or organization_id. Returns {enrichment_status, enrichment_updated_at, has_research}.

get_inbox_autopilot_status

Return the workspace's current inbox autopilot setting: {enabled, mode ('auto_safe'|'draft_all'|'off'), daily_cap}. Use this to confirm whether autopilot is active and how it is configured before changing it or reviewing drafts.

get_link_click_details

Link clicks for a campaign grouped by url, with total click counts and unique-prospect counts. Sorted by clicks desc.

get_organization

Get full details of an organization — domain, industry, employee count, funding, social URLs.

get_prospect

Get full profile of a prospect — name, title, company, LinkedIn, email, location, enrichment data.

get_prospect_campaign_activity

Chronological log of message events for a prospect across all campaigns (newest first).

get_prospect_engagement_timeline

Chronological email engagement timeline for a prospect (oldest first) — every open, click, reply, and bounce.

get_prospect_list

Get full details of a prospect list by ID — status, search config, result counts, timestamps.

get_signal_history

Return the detected SignalEvent rows for a single trigger — each event records whether the poll found changes, a summary, and the raw scrape. Returns {data: SignalEvent[]}.

get_signal_proposal

Fetch a single signal proposal by id, including its full recommendation (campaign name/description, workflow_config, target_prospect_ids, estimated contacts/credits, matched ICP, and entity). Returns {data: SignalProposal}, or a 404 error if not found.

get_upcoming_meetings

List upcoming non-cancelled meetings ordered by start time ascending. from defaults to now and to defaults to now + 30 days (both ISO8601). Returns {data: meeting row[]} (status one of scheduled|rescheduled|completed|no_show).

get_workspace_profile

Fetch workspace profile settings (company info) for the authenticated workspace via DigitalCrew API. Uses the MCP connection Authorization: Bearer token when set.

hosted_auth_link

Generate a short-lived URL for the user to connect a LinkedIn or email account via Unipile hosted auth.

import_prospect_list_csv

Create a new prospect list and import prospects in one call. Each row needs an email (for dedup).

launch_campaign

Launch a draft campaign — transitions draft → active and creates workflow executions for each prospect.

linkedin_cancel_invitation

Cancel/withdraw a sent LinkedIn invitation by its invitation_id (from list_invitations_sent).

linkedin_comment_on_post

Comment on a LinkedIn post.

linkedin_create_post

Create a LinkedIn post from the connected account.

linkedin_find_profile

Find a LinkedIn profile by name, company and/or title. Searches LinkedIn directly — always use this before any invitation or message. If multiple people share the name, returns candidates with ambiguous:true; show them to the user and ask which one. Never guess a slug or proceed when ambiguous.

linkedin_get_all_messages

Get all recent LinkedIn messages across all conversations.

linkedin_get_company_profile

Get a LinkedIn company profile by its identifier or slug.

linkedin_get_conversation_messages

Get messages in a specific LinkedIn conversation.

linkedin_get_own_profile

Get the profile of the connected LinkedIn account. Useful to confirm the account is active.

linkedin_get_profile

Get a full LinkedIn profile by slug (public identifier). Returns provider_id and profile data.

linkedin_get_user_posts

Get recent posts by a LinkedIn user.

linkedin_list_connections

List first-degree LinkedIn connections of the connected account.

linkedin_list_conversations

List LinkedIn conversations (inbox).

linkedin_list_invitations_received

List pending LinkedIn invitations received from others.

linkedin_list_invitations_sent

List pending LinkedIn invitations you have sent.

linkedin_react_to_post

React to a LinkedIn post.

linkedin_reply_in_chat

Reply in an existing LinkedIn conversation.

linkedin_search_people

Search LinkedIn for people by keywords.

linkedin_send_invitation

Send a LinkedIn connection request. ALWAYS call find_profile first to get provider_id.

linkedin_send_message

Send a LinkedIn direct message to start a new conversation. Requires existing connection or InMail credits.

list_accounts

List all connected LinkedIn and email accounts — name, email, status, daily limits.

list_campaigns

List all outreach campaigns. Filter by status, search by name, paginate and sort.

list_chat_messages

Get all messages in a conversation — body, direction (in/out), timestamp, status.

list_chats

List LinkedIn and email conversations — filter by channel, prospect, account, or archived status.

list_failed_requests

Inspect the dead-letter queue — write requests (POST/PATCH/DELETE) that exhausted all retries. Useful for forensics or manual replay. Backed by Redis if REDIS_URL is set, otherwise an in-memory ring buffer of up to 500 entries.

list_inbox_drafts

List the autopilot-generated reply drafts awaiting review (status='draft') for the workspace, newest first. Returns {data: InboxAutopilotAction[]}, each row including intent, sentiment, confidence, and the proposed reply_body. Review these before calling approve_inbox_draft or reject_inbox_draft.

list_intent_signals

List the workspace's intent triggers (optionally filtered by active state) so you can see what is being monitored and review recent signal activity. Returns {data: IntentTrigger[]}, each row including last_run_at and last_error. Use get_signal_history to drill into the detected events for a specific trigger.

list_organizations

List all organizations/companies — search by name or domain, filter by industry/country.

list_prospect_list_members

List all prospects in a specific list — paginated, searchable, sortable.

list_prospect_lists

List all prospect lists — name, status, result counts, and search criteria.

list_prospects

List prospects with rich filtering — search, status, org, titles, countries, industries, pagination, sorting.

list_signal_proposals

List the AI-generated campaign proposals produced from detected signals, optionally filtered by status (pending, approved, rejected, modified, launched, expired). An unknown status is ignored and all proposals are returned. Returns {data: SignalProposal[]}. Review pending proposals before approving them.

modify_proposal

Adjust a pending proposal WITHOUT launching it: pass modifications (titles, target_prospect_ids, campaign_name, campaign_description) to re-select prospects and regenerate the campaign workflow. The proposal stays pending so it can be reviewed and approved later. Returns the updated {data: SignalProposal}. Fails with 409 if the proposal is not pending, or 404 if not found.

notion_append_blocks

Append an array of Notion block JSON objects to an existing page (chunked into ≤100-block requests). Requires agent_settings.allow_notion_writes (default true). Returns { appended }.

notion_create_page

Create a new Notion page under a parent page, with an optional body of Notion block JSON. Requires agent_settings.allow_notion_writes (default true). Returns { id, url }.

notion_get_page

Fetch a Notion page object plus all of its child blocks (paginated). Returns { page, blocks }.

notion_publish_weekly_brief

Render a crm_weekly_brief_compose output as a DRAFT Notion page (H1 title + H2 section per part) under the workspace's Drafts/the assistant parent. Write-gated by agent_settings.allow_notion_writes. Defaults parent to agent_settings.notion_drafts_parent_id and template to agent_settings.notion_weekly_template_id. Returns { page_id, url, status:'draft', partial_success? }.

notion_search_pages

Search the connected Notion workspace for pages matching a free-text query. Returns [{ id, title, url }].

pause_campaign

Pause an active campaign — stops dequeueing new actions (in-flight calls finish).

propose_times

Return the n soonest available slots as a flat list — handy for offering a prospect a few concrete times. count is 1-50 (default 3); event_type_id defaults to the connection's default event type; time_zone is an optional IANA string. Returns {data: {eventTypeId, slots: [{start, end?}]}}. Fails with 409 if no calendar is connected.

reject_inbox_draft

Reject a drafted reply so it will not be sent, setting the action's status to 'rejected'. No message is sent. Returns the updated {data: InboxAutopilotAction}. Fails with 404 (draft not found) or 409 (action not in 'draft' status).

reject_proposal

Reject a pending proposal so it will not be launched. Returns the updated {data: SignalProposal (status 'rejected')}. Fails with 409 if the proposal is not pending.

remove_prospects_from_list

Remove prospects from a prospect list by their UUIDs.

restore_campaign

Restore an archived campaign back to draft status.

resume_campaign

Resume a paused campaign — transitions paused → active.

search_prospect_lists

Preview filter results without creating a list — search by titles, countries, industries, employee count, etc.

send_booking_link

Compose the rep's public Cal.com booking link so it can be shared with a prospect. Does NOT call Cal.com. Optionally pass prospect_id for context. Returns {data: {url, username}}. Fails with 409 if no calendar is connected.

send_chat_message

Send a manual reply in an existing Unibox chat. Channel (email/LinkedIn) is inferred from the chat.

send_new_email

Compose and send a brand-new email to any recipient, outside any chat or campaign. Sends from the workspace's connected email account. Use send_chat_message instead to reply within an existing conversation.

set_inbox_autopilot

Set the workspace's inbox autopilot configuration. enabled is the master kill switch (false = do nothing). When enabled, the autopilot reads each inbound email reply, drafts a suggested reply in the rep's voice, and NOTIFIES the user to review/approve it — it NEVER auto-sends; a human approves every reply (via list_inbox_drafts + approve_inbox_draft). mode: 'off' suppresses entirely; 'auto_safe' and 'draft_all' both draft-and-notify (auto-send is disabled in v1). daily_cap is reserved for a future auto-send mode. Returns the saved {data: inboxAutopilot}.

simulate_account_connected

Fire a Unipile account-connected webhook event. Use to test the handler that creates/updates an account record when Unipile finishes connecting.

simulate_account_status

Fire a Unipile account-status webhook. Use to test status changes (OK, CREDENTIALS, ERROR, CONNECTING, STOPPED). Useful for verifying that disconnected accounts are flagged correctly.

simulate_email_tracking

Fire a Unipile mail_opened or mail_link_clicked tracking event. Pass label as 'execution_state_id:node_id' to link the event to a campaign execution and increment open/click counts.

simulate_linkedin_messaging

Fire a Unipile LinkedIn messaging event (message_received, message_read, message_delivered, etc.). Use to test reply detection and campaign execution advancement on LinkedIn.

simulate_new_email

Fire a Unipile mail_received webhook. Use to test inbound email handling — reply detection, chat thread creation, and campaign execution advancement.

simulate_new_relation

Fire a Unipile new_relation event (LinkedIn invitation accepted). Use to test that the connection record is updated and any waiting campaign executions are advanced.

stop_campaign

Stop an active or paused campaign permanently — cannot be resumed.

update_account

Update account sender name, timezone, and working hours.

update_account_rate_limit

Update daily or weekly sending cap for a specific rate-limit row.

update_campaign

Partial update of a campaign — name, description, workflow, lists, accounts, scheduling.

update_campaign_memory

Record/update Max's durable memory for a campaign. Pass a partial 'memory' object (top-level keys merge; send the full array to change decisions/notes). Use it to remember ICP, decisions, and progress per campaign.

update_chat

Update chat metadata — title, read state, archived status, prospect link.

update_organization

Update an organization's fields (partial update).

update_prospect

Update a prospect's fields (partial update).

update_prospect_list

Update a prospect list (only list_name and status are editable).

update_workspace_profile

Create or update workspace profile settings for the authenticated workspace via DigitalCrew API (PUT upsert). Uses the MCP connection Authorization: Bearer token when set.

wait_for_prospect_list

Poll a prospect list (typically Apollo-backed) until its status becomes completed, failed, or cancelled — or the timeout elapses. Use this after apollo_create_list / apollo_add_more so the agent doesn't need to manage polling itself.

Tool definitions and validation use Zod per domain under features/pilot-tools/<domain>/schema.ts.

Related MCP server: Salesforce MCP Server

Requirements

  • Node.js (see Next.js 15 requirements)

  • pnpm (see packageManager in package.json)

Configuration

Set these environment variables (e.g. in .env.local for local dev, or in your host’s env for production):

Variable

Required

Description

DIGITALCREW_API_BASE_URL

Yes

Base URL of the Digital Crew API (no trailing slash)

MCP_GATEWAY_SECRET

Yes (prod)

Shared secret; callers send X-MCP-Gateway-Key on /mcp and /chat

MCP_ADMIN_GATEWAY_KEY

No

Separate key required for admin tools when ENABLE_ADMIN_TOOLS=true

ALLOW_ENV_TOKEN_FALLBACK

No

Set true only for legacy scripts that cannot send per-request tokens

DIGITALCREW_API_TOKEN or DIGITALCREW_BEARER_TOKEN

No*

Used only when ALLOW_ENV_TOKEN_FALLBACK=true

ENABLE_ADMIN_TOOLS

No

Set true to expose dead-letter / circuit-breaker admin tools

ENABLE_WEBHOOK_SIMULATORS

No

Set true to expose webhook simulation tools (dev/staging only)

CHAT_RATE_LIMIT_PER_MINUTE

No

Per-gateway-key chat limit (default 20)

CHAT_DAILY_REQUEST_CAP

No

Daily OpenRouter call cap per key (default 500)

REDIS_URL

No

Shared dead-letter queue and circuit-breaker state across instances

*Preferred auth: Authorization: Bearer <token> on the MCP HTTP request, or bearer_token on a tool call. Precedence: tool bearer_token → MCP Authorization → env (only if fallback enabled).

Getting started

pnpm install
# Create .env.local with DIGITALCREW_API_BASE_URL (and optional token vars)

pnpm dev

The MCP endpoint is:

  • Local: http://localhost:3000/mcp

  • Production: https://<your-deployment>/mcp

Point your MCP client at that URL using Streamable HTTP transport.

Optional: smoke-test with the bundled script

scripts/test-streamable-http-client.mjs lists tools via Streamable HTTP. It expects the @modelcontextprotocol/sdk client package available in your environment (install it if the script is not runnable yet):

node scripts/test-streamable-http-client.mjs http://localhost:3000

Note: SSE is currently disabled in app/mcp/route.ts (disableSse: true). The older scripts/test-client.mjs (SSE) is not aligned with the default setup unless you enable SSE and Redis per Vercel’s MCP pattern.

Stack

Deploying on Vercel

  • Enable Fluid compute for efficient execution.

  • Adjust maxDuration in app/mcp/route.ts if your plan allows (e.g. up to 800s on Pro/Enterprise).

  • SSE: If you switch disableSse to false, attach Redis and set REDIS_URL as required by the adapter. See also the Next.js MCP template.

Learn more

License

Private project ("private": true in package.json). Use and deployment are governed by your Digital Crew agreements.

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Digital-Crew-Technologies/max-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server