Skip to main content

MCP server for Keila API - comprehensive campaign and contact management

Project description

Keila MCP

PyPI Python

MCP server for Keila — gives any MCP-compatible AI assistant full control over your Keila email campaigns, contacts, segments and forms.

[!NOTE] Migrating from an earlier clone? The source directory was renamed from repo/ to keila-mcp/. Update any paths in your MCP client config accordingly.

  


  

Quickstart with uvx

If you have uv installed, no cloning or virtualenv needed:

{
  "mcpServers": {
    "keila": {
      "command": "uvx",
      "args": ["keila-mcp"],
      "env": {
        "KEILA_URL": "https://your-keila-instance.com",
        "KEILA_API_KEY": "your-api-key"
      }
    }
  }
}

Add this to your MCP client config and it works on first run. Skip to Client Configuration for client-specific formats.


Requirements

  


  

Installation

Choose where to install:

  • Global — use Keila MCP in any project: install in ~/.mcp/
  • Project — use it only in one project: install in your project folder, e.g. ~/Developer/my-project/.mcp/

  

macOS / Linux

  

# global
mkdir -p ~/.mcp && cd ~/.mcp

# or project-specific
mkdir -p ~/Developer/my-project/.mcp && cd ~/Developer/my-project/.mcp

git clone https://github.com/punkyard/keila-mcp.git keila-mcp
cd keila-mcp/repo
python -m venv .venv
source .venv/bin/activate
pip install .
pwd

Copy the path printed by pwd — you will paste it into your client config below.

  

Windows

  

# global
mkdir %USERPROFILE%\.mcp && cd %USERPROFILE%\.mcp

# or project-specific
mkdir C:\Users\your-username\Developer\my-project\.mcp && cd C:\Users\your-username\Developer\my-project\.mcp

git clone https://github.com/punkyard/keila-mcp.git keila-mcp
cd keila-mcp\repo
python -m venv .venv
.venv\Scripts\activate
pip install .
cd

Copy the path printed by cd — you will paste it into your client config below.

  


  

Client Setup

  

Every MCP client needs two things: the path to the Python interpreter and two environment variables.

Variable Value
KEILA_URL Your Keila instance URL, e.g. https://keila.mydomain.com
KEILA_API_KEY Create a Keila API key per project
KEILA_MCP_HTTP_PORT (optional) HTTP port for the MCP server. Default: 3001

  

Keila API Keys

  

[!IMPORTANT] In all examples below, replace /path/to/keila-mcp/repo with the path printed by pwd (or cd on Windows) at the end of the installation section.

  

Claude Desktop

  

File (macOS): ~/Library/Application Support/Claude/claude_desktop_config.json
File (Windows): %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "keila": {
      "command": "/path/to/keila-mcp/keila-mcp/.venv/bin/python",
      "args": ["/path/to/keila-mcp/keila-mcp/src/mcp_server.py"],
      "env": {
        "KEILA_URL": "https://your-keila-instance.com",
        "KEILA_API_KEY": "your-api-key"
      }
    }
  }
}

Fully quit and relaunch Claude Desktop after saving.

  

Claude Code

  

claude mcp add-json keila '{
  "type": "stdio",
  "command": "/path/to/keila-mcp/keila-mcp/.venv/bin/python",
  "args": ["/path/to/keila-mcp/keila-mcp/src/mcp_server.py"],
  "env": {
    "KEILA_URL": "https://your-keila-instance.com",
    "KEILA_API_KEY": "your-api-key"
  }
}'

Add --scope global to make it available in all projects.

  

Cursor · Cline / Roo Code · Windsurf · OpenClaw

  

  • Cursor: .cursor/mcp.json in your project, or ~/.cursor/mcp.json for global
  • Cline / Roo Code: MCP Servers config via the sidebar
  • Windsurf: ~/.codeium/windsurf/mcp_config.json
  • OpenClaw: ~/.openclaw/mcp.json
{
  "mcpServers": {
    "keila": {
      "command": "/path/to/keila-mcp/keila-mcp/.venv/bin/python",
      "args": ["/path/to/keila-mcp/keila-mcp/src/mcp_server.py"],
      "env": {
        "KEILA_URL": "https://your-keila-instance.com",
        "KEILA_API_KEY": "your-api-key"
      }
    }
  }
}

  

VS Code (GitHub Copilot Agent Mode)

  

Create .vscode/mcp.json in your project:

{
  "servers": {
    "keila": {
      "command": "/path/to/keila-mcp/keila-mcp/.venv/bin/python",
      "args": ["/path/to/keila-mcp/keila-mcp/src/mcp_server.py"],
      "env": {
        "KEILA_URL": "https://your-keila-instance.com",
        "KEILA_API_KEY": "${input:keilaApiKey}"
      }
    }
  },
  "inputs": [
    {
      "id": "keilaApiKey",
      "type": "promptString",
      "description": "Keila API Key",
      "password": true
    }
  ]
}

Requires Copilot Chat in Agent mode. VS Code will prompt for the API key on first use.

  

Zed

  

In ~/.config/zed/settings.json (global) or .zed/settings.json (project):

{
  "context_servers": {
    "keila": {
      "command": "/path/to/keila-mcp/keila-mcp/.venv/bin/python",
      "args": ["/path/to/keila-mcp/keila-mcp/src/mcp_server.py"],
      "env": {
        "KEILA_URL": "https://your-keila-instance.com",
        "KEILA_API_KEY": "your-api-key"
      }
    }
  }
}

  

OpenCode

  

In ~/.config/opencode/opencode.json (global) or opencode.json (project):

{
  "mcp": {
    "keila": {
      "type": "local",
      "command": ["/path/to/keila-mcp/keila-mcp/.venv/bin/python", "/path/to/keila-mcp/keila-mcp/src/mcp_server.py"],
      "env": {
        "KEILA_URL": "https://your-keila-instance.com",
        "KEILA_API_KEY": "your-api-key"
      }
    }
  }
}

  

Pi Agent

  

In ~/.pi/agent/mcp.json:

{
  "keila": {
    "command": "/path/to/keila-mcp/keila-mcp/.venv/bin/python",
    "args": ["/path/to/keila-mcp/keila-mcp/src/mcp_server.py"],
    "env": {
      "KEILA_URL": "https://your-keila-instance.com",
      "KEILA_API_KEY": "your-api-key"
    },
    "lifecycle": "on-demand"
  }
}

  

Hermes

  

In ~/.hermes/config.yaml:

mcp_servers:
  keila:
    command: /path/to/keila-mcp/keila-mcp/.venv/bin/python
    args:
      - /path/to/keila-mcp/keila-mcp/src/mcp_server.py
    env:
      KEILA_URL: https://your-keila-instance.com
      KEILA_API_KEY: your-api-key

  

OpenAI Codex CLI

  

File: ~/.codex/config.toml (global) or .codex/config.toml (project):

[mcp_servers.keila]
command = "/path/to/keila-mcp/keila-mcp/.venv/bin/python"
args = ["/path/to/keila-mcp/keila-mcp/src/mcp_server.py"]

[mcp_servers.keila.env]
KEILA_URL = "https://your-keila-instance.com"
KEILA_API_KEY = "your-api-key"

  


  

Running manually (for testing)

# stdio mode (default)
python src/mcp_server.py

# HTTP mode
python src/mcp_server.py --http
# optional: export KEILA_MCP_HTTP_PORT=8325

  


  

Tools

  

Tool Description
list_campaigns List all campaigns with optional status/search filter
create_campaign Create a new campaign
get_campaign Get a campaign by ID
update_campaign Update an existing campaign
delete_campaign Delete a campaign
send_campaign Send a campaign immediately
schedule_campaign Schedule a campaign for later delivery
create_contact Create a new contact
get_contact Get a contact by ID
update_contact Update a contact
delete_contact Delete a contact
list_contacts List contacts with optional filtering
update_contact_data Merge custom data fields on a contact
replace_contact_data Replace all custom data fields on a contact
list_senders List all senders
create_segment Create a new segment
list_segments List all segments
get_segment Get a segment by ID
update_segment Update a segment
delete_segment Delete a segment
list_forms List all forms
get_form Get a form by ID
create_form Create a new signup form
update_form Update a form
delete_form Delete a form
submit_form Submit a signup form on behalf of a contact

  

Campaigns

  

list_campaigns

List all email campaigns with optional filtering.

Param Type Required Description
status string No Filter by: draft/scheduled/sent/archived/paused
q string No Search by subject (case-insensitive substring)

  

create_campaign

Create a new email campaign.

Param Type Required Description
subject string Yes Campaign subject line
body_type string Yes Body type: markdown/text/block/mjml
text_body string No Plain text body
preview_text string No Preview text for inbox
sender_id string No Sender identity ID
segment_id string No Target segment ID
data object No Liquid template variables
do_not_track boolean No Disable open/click tracking

  

get_campaign

Get a single campaign by ID.

Param Type Required Description
id string Yes Campaign ID

  

update_campaign

Update an existing campaign.

Param Type Required Description
id string Yes Campaign ID
subject string No New subject line
preview_text string No New preview text

  

delete_campaign

Delete a campaign.

Param Type Required Description
id string Yes Campaign ID

  

send_campaign

Send a campaign immediately.

Param Type Required Description
id string Yes Campaign ID
sender_id string No Override sender identity

  

schedule_campaign

Schedule a campaign for later delivery.

Param Type Required Description
id string Yes Campaign ID
scheduled_for string Yes ISO 8601 datetime (e.g. 2026-06-01T09:00:00Z)

  

Contacts

  

create_contact

Create a new contact.

Param Type Required Description
email string Yes Email address
first_name string No First name
last_name string No Last name
external_id string No External system ID
status string No Status: active/inactive/bouncing/blocked/spam
data object No Custom fields

  

get_contact

Get a contact by ID, email, or external ID.

Param Type Required Description
id string Yes Contact identifier
id_type string No Lookup type: id (default)/email/external_id

  

update_contact

Update an existing contact.

Param Type Required Description
id string Yes Contact identifier
email string No New email
first_name string No New first name
last_name string No New last name
external_id string No New external ID
data object No New custom fields
id_type string No Lookup type: id (default)/email/external_id

  

delete_contact

Delete a contact.

Param Type Required Description
id string Yes Contact identifier
id_type string No Lookup type: id (default)/email/external_id

  

list_contacts

List contacts with pagination and optional search.

Param Type Required Description
page integer No Page number (default: 0)
page_size integer No Results per page (default: 50)
q string No Search query

  

Senders

  

list_senders

List all sender identities.

No parameters.

  

Contact Data

Custom data is a free-form JSON object attached to each contact. Use it to store any extra fields (e.g. plan, score, tags). Fields can be used as merge tags in campaigns via {{ contact.data.my_field }} and as segment filters. See Keila — Segments and Custom Data and Contacts API docs.

  

update_contact_data

  

Merge new key/value pairs into a contact's custom data field. Keys not present in data are preserved.

Param Type Required Description
id string Yes Contact ID (or email/external_id when id_type set)
data object Yes Key/value pairs to merge
id_type string No id (default), email, or external_id

  

replace_contact_data

Replace a contact's entire custom data field with the provided dict.

Param Type Required Description
id string Yes Contact ID (or email/external_id when id_type set)
data object Yes New data dict (replaces existing)
id_type string No id (default), email, or external_id

  

Segments

  

create_segment

Create a contact segment with a filter.

Param Type Required Description
name string Yes Segment name
filter object Yes Keila filter expression

  

list_segments

List all segments.

No parameters.

  

get_segment

Get a segment by ID.

Param Type Required Description
id string Yes Segment ID

  

delete_segment

Delete a segment.

Param Type Required Description
id string Yes Segment ID

  

update_segment

Update a segment's name and/or filter. At least one of name or filter must be provided.

Param Type Required Description
id string Yes Segment ID
name string No New segment name
filter object No New filter expression

  

Forms

  

list_forms

List all subscription forms.

No parameters.

  

get_form

Get a form by ID.

Param Type Required Description
id string Yes Form ID

  

create_form

Create a new subscription form.

Param Type Required Description
name string Yes Form name
sender_id string No Sender identity ID
fields array No Form field definitions
settings object No Form settings (double opt-in, redirect URLs, etc.)

  

delete_form

Delete a form.

Param Type Required Description
id string Yes Form ID

  

update_form

Update an existing signup form.

Param Type Required Description
id string Yes Form ID
name string No New form name
sender_id string No New sender identity ID
fields array No Replacement field definitions
settings object No Updated form settings

  

submit_form

Submit a signup form on behalf of a contact. Returns the created/updated contact on success, or {"data": {"double_opt_in_required": true}} if the form has double opt-in enabled.

Param Type Required Description
form_id string Yes Form ID
email string Yes Contact email address
first_name string No Contact first name
last_name string No Contact last name
external_id string No External identifier
status string No Contact status (e.g. active)
data object No Custom data key/value pairs

  


  

Development

pip install -e ".[dev]"
pytest tests/ -v

  

© 2026 — LICENSE AGPL-3.0

made with ⏳ by punkyard

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

keila_mcp-0.1.1.tar.gz (583.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

keila_mcp-0.1.1-py3-none-any.whl (25.6 kB view details)

Uploaded Python 3

File details

Details for the file keila_mcp-0.1.1.tar.gz.

File metadata

  • Download URL: keila_mcp-0.1.1.tar.gz
  • Upload date:
  • Size: 583.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for keila_mcp-0.1.1.tar.gz
Algorithm Hash digest
SHA256 730c57e5ae0aebaa74c6d1804edfa7d384679127d0cc911acf5a8a67094c6508
MD5 5f29f106ae72cee7434e529dc401ad7d
BLAKE2b-256 91f053763d6ccf4921570eb77931598691c1e80009beba9b0d2c1ecb565ccae7

See more details on using hashes here.

Provenance

The following attestation bundles were made for keila_mcp-0.1.1.tar.gz:

Publisher: publish.yml on punkyard/keila-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file keila_mcp-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: keila_mcp-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 25.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for keila_mcp-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 7dbf8b7017a82dcffd39a43309e85879349b3b91ffe700efcfe1e85cf99a2a2d
MD5 a7e4ffd08f4e879a63226c2f6cdd3bbf
BLAKE2b-256 540b1361f64e3bea2ad3d4c29eb8aa24c6b6ffd5a9dfc269cdaf98ef28dca751

See more details on using hashes here.

Provenance

The following attestation bundles were made for keila_mcp-0.1.1-py3-none-any.whl:

Publisher: publish.yml on punkyard/keila-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page