Skip to main content
Glama
Chatwoot MCP Server

Chatwoot MCP Server

by vivernet

Chatwoot MCP Server

Model Context Protocol (MCP) server for Chatwoot API integration. Enables AI assistants to manage customer conversations, messages, and contacts in Chatwoot.

Features

  • Conversations Management: List, filter, and retrieve conversation details

  • Message Operations: Read message history, send new messages, and delete messages

  • Type-Safe: Built with TypeScript using OpenAPI-generated types

  • Flexible Auth: Supports both API token (recommended) and JWT authentication

Related MCP server: @indica-facil/mcp-chatwoot

Tools Provided

Conversations

  • chatwoot_list_conversations - List conversations with filtering (status, assignee, inbox)

  • chatwoot_get_conversation - Get detailed info for a specific conversation

Messages

  • chatwoot_list_messages - List all messages in a conversation

  • chatwoot_create_message - Send a message or create an internal note

  • chatwoot_delete_message - Permanently delete a message and its attachments

Installation

npm install
npm run build

Configuration

The simplest method using your Chatwoot API token (no expiration).

Get your API token:

  1. Log in to your Chatwoot account

  2. Click your avatar → Profile Settings

  3. Scroll to bottom → Copy your "Access Token"

Configure .env:

CHATWOOT_BASE_URL="https://your-chatwoot-instance.com"
CHATWOOT_API_TOKEN="your_api_token_here"

Alternative: JWT Authentication

Use email/password if API tokens don't work on your instance (requires password for token refresh).

CHATWOOT_BASE_URL="https://your-chatwoot-instance.com"
CHATWOOT_EMAIL="your@email.com"
CHATWOOT_PASSWORD="your_password"

Note: JWT tokens expire and require the password for auto-refresh.

Important for Self-Hosted Instances

If using nginx as reverse proxy (e.g., CapRover), add this to nginx config to support API tokens:

server {
    ...
    underscores_in_headers on;  # Required for api_access_token header
    ...
}

Usage

Running the Server

npm start

Development Mode (with auto-reload)

npm run dev

Using with Claude Code

claude mcp add chatwoot \
  -e CHATWOOT_BASE_URL="https://your-instance.com" \
  -e CHATWOOT_API_TOKEN="your_token" \
  -- node /path/to/chatwoot-mcp-server/dist/index.js

Using with Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "chatwoot": {
      "command": "node",
      "args": ["/path/to/chatwoot-mcp-server/dist/index.js"],
      "env": {
        "CHATWOOT_BASE_URL": "https://your-chatwoot-instance.com",
        "CHATWOOT_API_TOKEN": "your_api_token"
      }
    }
  }
}

Example Queries

Once connected, you can ask Claude things like:

  • "Show me all open conversations in account 3"

  • "What are the details of conversation #123?"

  • "List all messages in conversation #456"

  • "Send a reply to conversation #789 saying 'Thank you for contacting us!'"

  • "Add an internal note to conversation #101 about the customer's issue"

Testing

Run integration tests:

npm test

Watch mode:

npm run test:watch

Project Structure

chatwoot-mcp-server/
├── src/
│   ├── index.ts                  # Main server entry point
│   ├── constants.ts              # Shared constants
│   ├── chatwoot-types.ts         # Generated OpenAPI types
│   ├── services/
│   │   ├── chatwoot-client.ts    # API client with auth
│   │   ├── chatwoot-auth.ts      # JWT authentication
│   │   ├── token-cache.ts        # JWT token caching
│   │   └── error-handler.ts      # Error handling utilities
│   ├── schemas/
│   │   └── common.ts             # Shared Zod schemas
│   └── tools/
│       ├── conversations.ts      # Conversation tools
│       └── messages.ts           # Message tools
├── test/                         # Integration tests
├── swagger.json                  # Chatwoot OpenAPI spec
└── package.json

Development

Regenerating Types

If the Chatwoot API changes, regenerate types:

npm run generate-types

Adding New Tools

  1. Create a new file in src/tools/

  2. Define Zod schemas for input validation

  3. Implement the tool function

  4. Register the tool in src/index.ts

Building

npm run build

Builds TypeScript to JavaScript in the dist/ directory.

Troubleshooting

API Token Returns 401

If using a self-hosted instance with nginx, ensure underscores_in_headers on; is set in your nginx config. This is required because api_access_token contains underscores.

JWT Tokens Expire

If using JWT authentication, tokens expire (typically after 2 weeks). Keep CHATWOOT_PASSWORD in .env for automatic refresh, or switch to API token authentication.

Tech Stack

  • TypeScript - Type-safe development

  • openapi-fetch - Type-safe API client

  • openapi-typescript - Generate types from OpenAPI spec

  • Zod - Runtime input validation

  • @modelcontextprotocol/sdk - MCP server framework

  • Vitest - Testing framework

License

MIT

Contributing

Contributions are welcome! Additional tools that could be added:

  • Contact management (create, update, search)

  • Team and agent operations

  • Inbox configuration

  • Labels and custom attributes

  • Reports and analytics

  • Bulk operations


Fork: local build for github.com/vivernet/chatwoot-mcp

This copy is a fork of chatwoot-mcp-server@1.0.0 (see UPSTREAM.md), run from source instead of via npx, with one added tool.

Changes in this fork

  • New tool chatwoot_toggle_status — changes a conversation status (open / resolved / pending / snoozed), including optional snoozed_until (Unix timestamp in seconds) for scheduled snooze. Implemented in dist/tools/conversations.js + registered in dist/index.js; uses the stock Chatwoot POST /api/v1/accounts/{account_id}/conversations/{conversation_id}/toggle_status endpoint (already present in the generated OpenAPI types).

  • New tool chatwoot_delete_message — permanently deletes a message and its attachments through Chatwoot's DELETE /api/v1/accounts/{account_id}/conversations/{conversation_id}/messages/{message_id} endpoint. The tool is marked destructive and requires explicit human approval through the companion chatwoot-approval plugin.

  • Version bumped to 1.2.0; start script runs node dist/index.js.

Running locally (no npx)

node dist/index.js

Needs the same env vars as upstream: CHATWOOT_BASE_URL plus either CHATWOOT_API_TOKEN or CHATWOOT_EMAIL/CHATWOOT_PASSWORD.

Smoke test

python3 tests/mcp_smoke.py        # stub HTTP backend; verifies status toggle and message deletion

Hermes Agent wiring

Hermes config.yaml → mcp_servers.chatwoot:

mcp_servers:
  chatwoot:
    command: node
    args: ["/absolute/path/to/chatwoot-mcp-server/dist/index.js"]
    env:
      CHATWOOT_BASE_URL: ${env:CHATWOOT_BASE_URL}
      CHATWOOT_EMAIL: ${env:CHATWOOT_EMAIL}
      CHATWOOT_PASSWORD: ${env:CHATWOOT_PASSWORD}

Companion approval plugin (guards chatwoot_create_message, chatwoot_toggle_status, and chatwoot_delete_message behind the human-approval gate): see the chatwoot-approval Hermes plugin.

Available Tools

5 tools
chatwoot_create_messageCreate Message in ConversationA

Create a new message in a Chatwoot conversation.

This tool sends a message in an existing conversation. Can be used for outgoing messages to customers or private internal notes.

Args:

  • account_id (number): The numeric ID of the Chatwoot account (required)

  • conversation_id (number): The ID of the conversation (required)

  • content (string): The message content (required)

  • message_type (string): Type of message - "outgoing" or "incoming" (default: "outgoing")

  • private (boolean): Whether this is a private internal note (default: false)

Returns: Created message details including ID and confirmation

Examples:

  • Send a reply: { account_id: 1, conversation_id: 123, content: "Thank you for contacting us!" }

  • Add internal note: { account_id: 1, conversation_id: 123, content: "Customer called for follow-up", private: true }

Inputs: content (required), account_id (required), conversation_id (required), private, +1 more.

chatwoot_get_conversationGet Chatwoot Conversation DetailsA
Read-onlyIdempotent

Get detailed information about a specific Chatwoot conversation.

This tool retrieves full details for a single conversation including contact info, assignee, labels, and custom attributes.

Args:

  • account_id (number): The numeric ID of the Chatwoot account (required)

  • conversation_id (number): The ID of the conversation to retrieve (required)

  • response_format (string): Output format - "markdown" or "json" (default: "markdown")

Returns: Full conversation details including:

  • Status, inbox, and metadata

  • Complete contact information

  • Assignee details

  • Labels and custom attributes

  • Message statistics

Examples:

  • Get conversation details: { account_id: 1, conversation_id: 123 }

Inputs: account_id (required), conversation_id (required), response_format.

chatwoot_list_conversationsList Chatwoot ConversationsA
Read-onlyIdempotent

List conversations from a Chatwoot account with filtering options.

This tool retrieves conversations from Chatwoot, allowing you to filter by status, assignee, and inbox. Supports pagination for large result sets.

Args:

  • account_id (number): The numeric ID of the Chatwoot account (required)

  • page (number): Page number for pagination, starts at 1 (default: 1)

  • status (string): Filter by conversation status - "open", "resolved", "pending", "snoozed", or "all" (default: "open")

  • assignee_type (string): Filter by assignee - "me", "unassigned", or "all" (optional)

  • inbox_id (number): Filter by specific inbox ID (optional)

  • response_format (string): Output format - "markdown" or "json" (default: "markdown")

Returns: A list of conversations with details including:

  • Conversation ID, status, and inbox

  • Contact information (name, email)

  • Assignee details

  • Message count and unread count

  • Last activity timestamp

Examples:

  • List all open conversations: { account_id: 1, status: "open" }

  • List unassigned conversations: { account_id: 1, assignee_type: "unassigned" }

  • List conversations in specific inbox: { account_id: 1, inbox_id: 5 }

Inputs: account_id (required), page, status, inbox_id, +2 more.

chatwoot_list_messagesList Messages in ConversationA
Read-onlyIdempotent

List all messages in a Chatwoot conversation.

This tool retrieves all messages from a specific conversation, including message content, sender information, timestamps, and attachments.

Args:

  • account_id (number): The numeric ID of the Chatwoot account (required)

  • conversation_id (number): The ID of the conversation (required)

  • response_format (string): Output format - "markdown" or "json" (default: "markdown")

Returns: List of messages with:

  • Message ID and content

  • Message type (incoming/outgoing)

  • Sender information (name, type)

  • Timestamp

  • Attachment information

  • Private flag (for internal notes)

Examples:

  • List all messages: { account_id: 1, conversation_id: 123 }

Inputs: account_id (required), conversation_id (required), response_format.

chatwoot_toggle_statusChange Conversation StatusA
Destructive

Change the status of a Chatwoot conversation (open/resolved/pending/snoozed).

This tool updates the conversation status. Use "snoozed" together with snoozed_until to schedule a reopen.

Args:

  • account_id (number): The numeric ID of the Chatwoot account (required)

  • conversation_id (number): The ID of the conversation (required)

  • status (string): Target status: open, resolved, pending or snoozed (required)

  • snoozed_until (number): Optional Unix timestamp (seconds) when a snoozed conversation reopens

Inputs: status (required), account_id (required), conversation_id (required), snoozed_until.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.9/5.0

    Scored across 5 tools

    Disambiguation5/5

    Each tool has a clearly distinct purpose: listing conversations, getting one conversation, changing status, listing messages, and creating a message. The list/get and message read/write pairs are cleanly separated by scope and action.

    Naming Consistency5/5

    All tools use the same chatwoot_ prefix and snake_case verb_noun pattern. The convention is predictable throughout, with only minor semantic looseness in 'toggle_status' since it sets rather than toggles.

    Tool Count5/5

    Five tools is a compact, well-scoped set for conversation-centric Chatwoot workflows. Each tool earns its place without redundancy or excessive surface area.

    Completeness3/5

    The core conversation read/reply/status workflow is covered, but notable Chatwoot operations are absent: creating conversations, assigning agents, managing labels, and listing contacts or inboxes. These gaps will limit common support workflows.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Exposes the full Chatwoot API as 129 tools for AI assistants, enabling account, contact, conversation, message, inbox, team, report, help center, automation, and custom attribute management, plus exclusive Kanban and scheduled message features.
      14 npm
      MIT
    • A
      license
      B
      quality
      C
      maintenance
      Provides AI assistants with read-only access to Chatwoot analytics and operational data, including conversations, agents, inboxes, teams, CSAT, and real-time metrics.
      30
      1
      MIT
    • F
      license
      Not graded
      quality
      A
      maintenance
      Enables AI assistants to access and manage CRM data by creating contacts and companies, retrieving activities and conversations, and performing semantic search over previously retrieved information with built-in vector storage and caching.
      -