Platform · MCP

Your AI tools, wired into HAL.

HAL hosts a stateless HTTP MCP endpoint. Point Claude, your agents, or your coding tools at it and they can read conversations, work the CRM, and pull knowledge — with HAL's boundaries enforced server-side.

Endpoint & auth

POST https://api.chatwithhal.com/mcp
X-API-Key: <account-scoped MCP key>

The MCP key is account-scoped (Settings → API) and separate from project API keys. The transport is stateless HTTP — no stdio, no local process.

Example client config

{
  "mcpServers": {
    "hal": {
      "type": "http",
      "url": "https://api.chatwithhal.com/mcp",
      "headers": { "X-API-Key": "YOUR_MCP_KEY" }
    }
  }
}

Always list projects first

The key spans your account, so every project-scoped tool takes a project_id or project_slug. Call list_projects once, cache the slugs, and pass one on every subsequent call. For email features specifically, call get_email_capabilities_overview next — it explains campaigns vs. workflows vs. broadcasts, templates, sender domains, and the other choices before you start creating things.

What the endpoint can do

Read projects and conversations

List projects, inspect conversations, and use customer context without rebuilding the model outside HAL.

Work with CRM and knowledge

Read or update company records, articles, groups, and other structured project data through tools.

Author and monitor interactive guides

Create, update, and delete step-by-step walkthroughs, then keep them healthy: validate_guide checks selectors and start locations against real pages, and get_guide_stats reports triggers, completions, and drop-off per step.

Stay within HAL boundaries

MCP gives AI clients access to HAL. It does not turn HAL into an unsupervised external execution layer.

Generate HAL AI reply suggestions

Ask HAL for an advisory evidence-backed draft, then combine it with the conversation when composing the final answer.

Build visitor workflows

Author the same branching trigger → condition → action graphs as the dashboard builder. validate_workflow checks the graph before you save, reorder_workflows sets priority, and list_workflow_executions shows what actually ran.

Design and test lifecycle email

Build typed content blocks — heading, paragraph, button, image, divider, spacer, footer note — or reusable templates, set project-wide email defaults, and send a real test. Test sends only reach addresses that belong to a user on your account.

Trigger workflows from your own events

track_event fires API-triggered workflows exactly like the public track-event API, for real contacts. Pass dry_run: true to preview which workflows would match before anything is tracked or sent.

Tool map

  • Conversationsget_conversation (messages + attachment metadata), get_conversation_image (native image content for private visitor attachments; >2MB images are resized ≤1600×1600), reply_to_conversation.
  • CRMlist_contacts, create_contact/update_contact, list_crm_stages, list_companies (filter by stage), list_companies_by_stage (read-only board with stage totals), get_company, create_company/update_company, link_contact_to_company.
  • AIgenerate_ai_response_suggestion: HAL's evidence-backed draft for a conversation. Advisory only — it is stored as a non-sendable suggestion and never delivered to the visitor; your agent composes and sends its own reply via reply_to_conversation.
  • Migrationimport_conversation / import_conversations (up to 100 per call): silent imports with no webhooks, notifications, or AI side effects. Visitor matching order: email → user_id → external_id → create. 1–1000 messages per conversation, visitor / agent / system roles, internal notes supported.
  • Visitor workflowsget_workflow_builder_reference (trigger shapes, graph rules, condition operators, email block types), list_workflows / get_workflow / create_workflow / update_workflow / delete_workflow, validate_workflow (checks a full graph without saving it), set_workflow_enabled, reorder_workflows, list_workflow_executions / get_workflow_execution.
  • Lifecycle emaillist_email_templates / create_email_template / update_email_template / delete_email_template, preview_email_template / validate_email_template, get_workflow_email_defaults / update_workflow_email_defaults (project-wide defaults for new send_email nodes). For simple linear campaigns there's also create_email_campaign / update_email_campaign / enable_email_campaign / disable_email_campaign / delete_email_campaign — a trigger → conditions → one email shape; branching workflows built with create_workflow report editable_as_campaign: false and must be edited with update_workflow instead. Image blocks need a hosted URL — upload_email_image (from base64 bytes or a source URL) / list_email_images / delete_email_image manage a per-project image library and return an email_url to use in image blocks. Blocks also include full-width section containers (background color, padding, an optional full-bleed hero that breaks out of the card's side padding, and color overrides for their children), list and quote blocks, and a theme that supports light/dark color pairs — call get_workflow_builder_reference for the full block/theme schema and a worked example_newsletter document.
  • Broadcasts — one-off emails (same block design as lifecycle email) sent to an audience of contacts, now or scheduled. list_broadcasts / get_broadcast / create_broadcast / update_broadcast / delete_broadcast (accepts a category, default marketing), preview_broadcast_audience (count, suppressed count for that category, and a sample before you send), get_broadcast_audience_fields (builtin contact/company fields, sampled metadata keys, valid operators). schedule_broadcast / cancel_broadcast, list_broadcast_recipients for per-recipient delivery status. send_broadcast_now emails the real, live audience immediately — it requires confirm_recipient_count to exactly match the current preview_broadcast_audience count, so always preview and get explicit confirmation first.
  • Email categories & suppressionlist_email_categories / update_email_categories manage a project's unsubscribe categories (e.g. marketing, product updates, transactional); a category with unsubscribable: false always sends unless the address bounced or complained. list_email_suppressions, suppress_email_recipient, unsuppress_email_recipient, and get_email_unsubscribe_status all take an optional category (default all, meaning every category) so an address can opt out of just one category instead of everything.
  • Test sendssend_test_workflow_email, send_test_email_template, send_test_email_campaign, and send_test_broadcast_email only deliver to addresses returned by list_test_email_recipients — users on your own account, never a visitor.
  • Eventstrack_event tracks a lifecycle event exactly like the public track-event API and immediately fires matching enabled api_trigger workflows for real contacts, including real email sends. Pass dry_run: true to see which workflows would match without tracking anything or sending email; list_event_names shows event names already seen in a project.

Metadata, same rules everywhere

Contact and company writes accept the same flat metadata as the REST API — plain scalars, ≤ 50 keys, ≤ 10KB, replace-on-write. The limits live in CRM data model.

Boundaries that stay enforced

  • Account scoping — tools only see the account the key belongs to.
  • AI guardrails — the suggestion tool runs the same evidence, confidence, and injection checks as the dashboard.
  • No silent sends — nothing reaches a visitor unless a tool explicitly calls reply_to_conversation.
  • Test emails stay internal — send_test_workflow_email, send_test_email_template, and send_test_email_campaign reject any recipient that isn't a user on your account.
  • track_event can trigger real email sends — always check dry_run results before calling it without dry_run against real contacts.

Ideas

  • Point a coding agent at production support: "summarize this week's billing conversations and open an issue for the top bug."
  • Migrate from another helpdesk with the import tools, then let an agent reconcile stage totals against the old system.
  • Let an internal AI assistant answer "what's the status of Acme?" from live CRM state.