Skip to main content
Glama
homeserverhq

Keila MCP Server

by homeserverhq
README.md
# Keila MCP Server

This repository contains a Model Context Protocol (MCP) server that acts
as a secure, multi-tenant proxy between an AI Assistant and the Keila
backend API. It exposes **34 MCP tools** covering 6 resource domains
with full CRUD, transactional messaging, and system operations.

## โœจ Features

- **๐Ÿ”‘ Identity Passthrough** โ€” Extracts the `Authorization: Bearer <token>`
  header from incoming HTTP requests and forwards it to the Keila API
  without server-side authentication.
- **๐Ÿ‘ฅ Multi-Tenancy** โ€” Uses Python `contextvars` to maintain thread-safe
  user identity isolation, ensuring all AI-driven actions are scoped to
  the authenticated user's permissions.
- **๐Ÿ“Š Full Keila Coverage** โ€” 34 tools mapped to Keila REST API
  endpoints across 6 resource domains.
- **โšก TOON Optimization** โ€” Bulk list responses are automatically compressed
  using TOON (Token-Optimized Object Notation) to reduce token consumption
  and maximize context window efficiency.
- **๐Ÿš€ Efficient Gets** โ€” GET responses return only commonly used fields by
  default. Full objects are available via an `include_all_fields` flag.
- **๐Ÿงช Comprehensive Testing** โ€” 75 automated tests covering all tool
  domains, run via the test runner pipeline.
- **๐Ÿท๏ธ Tool Annotations** โ€” All tools expose standard MCP ToolAnnotations
  hints (readOnlyHint, destructiveHint, idempotentHint, openWorldHint). The
  tags field carries grouping metadata (basic/primary/advanced + keila).

## ๐Ÿ”ง Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `KEILA_BASE_URL` | Yes | Docker-internal URL of the Keila API (e.g. `http://keila-app:4000`). |
| `MCP_SERVER_PORT` | Yes | Port number the MCP server listens on |
| `ALLOW_ALL_AGGREGATE` | No | When `true`, aggregate listing tools honor the `include_all_fields` parameter. When `false` (default), the parameter is silently forced to `False` for aggregate list operations. |
| `IS_STATEFUL` | No | When `true`, uses stateful Streamable HTTP with session tracking. When `false` (default), uses stateless mode. |

## ๐Ÿ“ฆ Installation & Local Development

1. Ensure you have Python 3.12+ installed.
2. Install dependencies:
    ```bash
    pip install fastmcp httpx pydantic uvicorn toon-mcp-server
    ```
3. Run the server:
    ```bash
    export KEILA_BASE_URL=http://keila-app:4000
    export MCP_SERVER_PORT=80
    python -m src.main
    ```

## ๐Ÿณ Docker Deployment

Build and run the server using Docker:

```bash
docker build -t keila-mcp:latest .
docker run -d --name keila-mcp \
    -e KEILA_BASE_URL="http://keila-app:4000" \
    -e MCP_SERVER_PORT=80 \
    -e ALLOW_ALL_AGGREGATE=false \
    keila-mcp:latest
```

The MCP server serves at `http://keila-mcp:80/mcp` (Streamable HTTP).

## โš ๏ธ Important Notes

- **๐Ÿ“‹ `include_all_fields`** โ€” The `include_all_fields` parameter (available
  on all `get_*` and `list_*` tools) controls whether all available fields
  are included in responses. Defaults to `False` for performance; set to
  `True` only when additional fields are needed.
- **๐Ÿ”’ `ALLOW_ALL_AGGREGATE`** โ€” Controls whether aggregate listing tools respect the `include_all_fields` parameter. When set to `false` (default), all aggregate list operations silently return only default fields regardless of the caller's request.
- **โšก TOON Compression** โ€” All bulk list responses are automatically
  compressed using TOON to reduce token consumption by 30โ€“60%.
- **๐Ÿ“ Required Fields & Defaults** โ€” Each `create_*` tool requires specific
  key fields. All other fields default to empty strings or reasonable values.

## ๐Ÿ› ๏ธ API Tool Mapping

The server implements 34 MCP tools organized into the following categories:

### ๐Ÿ“ง Campaigns (7 tools)

- `list_all_campaigns` โ€” List all campaign records
- `get_campaign_by_id` โ€” Get a single campaign by ID
- `create_campaign` โ€” Create a new campaign
- `update_campaign` โ€” Update an existing campaign
- `delete_campaign_by_id` โ€” Delete a campaign by ID
- `send_campaign` โ€” Queue a campaign for immediate delivery
- `schedule_campaign` โ€” Schedule a campaign for future delivery

### ๐ŸŽฏ Segments (5 tools)

- `list_all_segments` โ€” List all segment records
- `get_segment_by_id` โ€” Get a single segment by ID
- `create_segment` โ€” Create a new segment
- `update_segment` โ€” Update an existing segment
- `delete_segment_by_id` โ€” Delete a segment by ID

### ๐Ÿ‘ฅ Contacts (7 tools)

- `list_all_contacts` โ€” List all contact records
- `get_contact_by_id` โ€” Get a single contact by ID, email, or external ID
- `create_contact` โ€” Create a new contact
- `update_contact` โ€” Update an existing contact
- `delete_contact_by_id` โ€” Delete a contact by ID, email, or external ID
- `update_contact_data` โ€” Shallow-merge custom data fields on a contact
- `replace_contact_data` โ€” Replace all custom data fields on a contact

### ๐Ÿ“ Forms (6 tools)

- `list_all_forms` โ€” List all form records
- `get_form_by_id` โ€” Get a single form by ID
- `create_form` โ€” Create a new form
- `update_form` โ€” Update an existing form
- `delete_form_by_id` โ€” Delete a form by ID
- `submit_form` โ€” Submit a form to create or update a contact

### ๐Ÿ“„ Templates (5 tools)

- `list_all_templates` โ€” List all template records
- `get_template_by_id` โ€” Get a single template by ID
- `create_template` โ€” Create a new template
- `update_template` โ€” Update an existing template
- `delete_template_by_id` โ€” Delete a template by ID

### ๐Ÿ› ๏ธ Senders, Transactional Messages & System Tools (4 tools)

- `list_all_senders` โ€” List all sender records
- `send_transactional_message` โ€” Send a transactional message
- `render_transactional_message` โ€” Render a transactional message without sending it
- `check_server_status` โ€” Check connectivity to the Keila backend