How to integrate Klaviyo MCP with Google ADK

Framework Integration Gradient
Klaviyo Logo
Google ADK Logo
divider

Introduction

This guide walks you through connecting Klaviyo to Google ADK using the Composio tool router. By the end, you'll have a working Klaviyo agent that can add new subscribers to main email list, clone last week's campaign for reuse, estimate recipients for upcoming product launch, create back-in-stock alerts for a product through natural language commands.

This guide will help you understand how to give your Google ADK agent real control over a Klaviyo account through Composio's Klaviyo MCP server.

Before we dive in, let's take a quick look at the key ideas and tools involved.

TL;DR

Here's what you'll learn:
  • Get a Klaviyo account set up and connected to Composio
  • Install the Google ADK and Composio packages
  • Create a Composio Tool Router session for Klaviyo
  • Build an agent that connects to Klaviyo through MCP
  • Interact with Klaviyo using natural language

What is Google ADK?

Google ADK (Agents Development Kit) is Google's framework for building AI agents powered by Gemini models. It provides tools for creating agents that can use external services through the Model Context Protocol.

Key features include:

  • Gemini Integration: Native support for Google's Gemini models
  • MCP Toolset: Built-in support for Model Context Protocol tools
  • Streamable HTTP: Connect to external services through streamable HTTP
  • CLI and Web UI: Run agents via command line or web interface

What is the Klaviyo MCP server, and what's possible with it?

The Klaviyo MCP server is an implementation of the Model Context Protocol that connects your AI agent and assistants like Claude, Cursor, etc directly to your Klaviyo account. It provides structured and secure access to your marketing campaigns, contact lists, and automation features, so your agent can perform actions like creating campaigns, managing subscribers, sending messages, and analyzing engagement—all on your behalf.

  • Automated campaign creation and sending: Instantly have your agent create new marketing campaigns, clone existing ones, and trigger campaign sends to targeted audiences.
  • Subscriber and list management: Add or update profiles in specific Klaviyo lists, subscribe contacts to marketing lists, and ensure your audience is always up to date.
  • Event and engagement tracking: Automatically record customer activities or bulk-create profile events to power segmentation and analytics.
  • Catalog and back-in-stock automation: Let your agent create product catalog categories, manage restock alerts, and help drive timely customer notifications about inventory.
  • Campaign recipient estimation and analytics: Start background jobs to estimate campaign reach and analyze how many recipients meet your targeting criteria before a send.

Supported Tools & Triggers

Tools
Add Profile to ListAdd profiles to a klaviyo list by profile ids or email addresses.
Assign campaign message templateCreates a non-reusable version of the template and assigns it to the message.
Bulk create client eventsUse the client-side endpoint with a public api key to track profile activity.
Bulk create eventsThis api endpoint creates or updates profiles by batching up to 1,000 events, with a 5mb payload limit.
Create back in stock subscriptionUse the server-side endpoint to subscribe to restock alerts, following the back in stock api guide.
Create campaignCreates a campaign given a set of parameters, then returns it.
Create campaign cloneClones an existing campaign, returning a new campaign based on the original with a new id and name.
Create Campaign Recipient Estimation JobStart an asynchronous task to estimate the number of recipients for a campaign.
Create campaign send jobTrigger a campaign to send asynchronously*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:write`
Create catalog categoryCreate a new catalog category.
Create catalog category relationships itemsCreate a new item relationship for the given category id.
Create catalog itemCreate a new catalog item.
Create catalog item relationships categoriesCreate a new catalog category relationship for the given item id.
Create catalog variantCreate a new variant for a related catalog item.
Create client back in stock subscriptionUse the endpoint for client-side back in stock notifications with a public api key.
Create client eventCreate client-side events to track profiles using a public api key, not for updating identifiers (server-side only).
Create client subscriptionEndpoint manages email/sms opt-ins using consent and requires public api key for client use.
Create couponCreates a new coupon.
Create coupon codeSynchronously creates a coupon code for the given coupon.
Create eventCreate or update a profile event with minimum identifiers and metric name.
Create listCreate a new list.
Create or update client profileUpdate user profiles without tracking using a public client-side api; use a private server-side api for identifier changes.
Create or update client push tokenThis endpoint for mobile sdks (ios & android) creates/updates push tokens using a public api key.
Create or Update ProfileCreate or update a profile in klaviyo with the given attributes.
Create or update push tokenMigrate or create push tokens with klaviyo's endpoint, utilizing their mobile sdks for ios & android.
Create profileCreate a new profile.
Create segmentCreate a segment.
Create tagSummary: instructions on creating a tag within an account's designated tag group with a maximum of 500 tags, with optional tag group specification.
Create tag groupCreate tag groups up to 50 per account, defaulting to non-exclusive unless specified.
Create tag relationships campaignsSummary: link a tag to campaigns, ensuring a limit of 100 tags per campaign.
Create tag relationships flowsAssign tags to flows using their ids in the request body, ensuring a flow is not linked to over 100 tags.
Create tag relationships listsSummary: a tag can be added to one or more lists, with a max of 100 tags per list.
Create tag relationships segmentsSummary: set tag associations with segments using the request body, limited to one tag per segment and up to 100 tags per segment.
Create templateSummary: custom html templates can be created unless an account reaches 1,000 template limit.
Create template cloneClone a template by its id, but cloning fails if account has 1,000+ templates.
Create template renderRender an email template with specific context and sparse fieldsets, then get html/plain text.
Create webhookCreate a new webhook*rate limits*:burst: `1/s`steady: `15/m` **scopes:** `webhooks:write`
Delete campaignDelete a campaign with the given campaign id.
Delete catalog categoryDelete a catalog category using the given category id.
Delete catalog category relationships itemsDelete item relationships for the given category id.
Delete catalog itemDelete a catalog item with the given item id.
Delete catalog item relationships categoriesDelete catalog category relationships for the given item id.
Delete catalog variantDelete a catalog item variant with the given variant id.
Delete couponDelete the coupon with the given coupon id.
Delete coupon codeDeletes a coupon code specified by the given identifier synchronously.
Delete flowDelete a flow with the given flow id.
Delete listDelete a list with the given list id.
Delete segmentDelete a segment with the given segment id.
Delete tagDelete the tag with the given tag id.
Delete tag groupDelete a specified tag group and its contents; associated resource links will be removed.
Delete tag relationships campaignsDisconnect a tag from campaigns using the campaign id(s) in the request body.
Delete tag relationships flowsRemove a tag's association with one or more flows.
Delete tag relationships listsRemove a tag's association with one or more lists.
Delete tag relationships segmentsUse the request body to de-associate a tag from specified segment ids.
Delete templateDelete a template with the given template id.
Delete webhookDelete a webhook with the given id.
Get accountRetrieve a single account object by its account id.
Get accountsUse a private api key to fetch an associated account's details like contact info, timezone, and currency, as well as validate the key.
Get bulk profile import jobGet a bulk profile import job with the given job id.
Get bulk profile import job errorsGet import errors for the bulk profile import job with the given id.
Get bulk profile import job listsGet list for the bulk profile import job with the given id.
Get bulk profile import job profilesGet profiles for the bulk profile import job with the given id.
Get bulk profile import job relationships listsGet list relationship for the bulk profile import job with the given id.
Get bulk profile import job relationships profilesGet profile relationships for the bulk profile import job with the given id.
Get bulk profile import jobsGet all bulk profile import jobs.
Get CampaignRetrieve a specific campaign by its id from klaviyo.
Get campaign campaign messagesReturn all messages that belong to the given campaign.
Get campaign messageReturns a specific message based on a required id.
Get campaign message campaignReturn the related campaign*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:read`
Get campaign message relationships campaignReturns the id of the related campaign*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:read`
Get campaign message relationships templateReturns the id of the related template*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:read` `templates:read`
Get campaign message templateReturn the related template*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:read` `templates:read`
Get campaign recipient estimationGet estimated recipients for a given campaign id using `create campaign recipient estimation job`.
Get campaign recipient estimation jobRetrieve the status of a recipient estimation job triggered with the `create campaign recipient estimation job` endpoint.
Get campaign relationships campaign messagesReturns the ids of all messages associated with the given campaign.
Get campaign relationships tagsReturns the ids of all tags associated with the given campaign.
Get CampaignsRetrieve campaigns from your klaviyo account.
Get campaign send jobGet a campaign send job*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:read`
Get campaign tagsReturn all tags that belong to the given campaign.
Get catalog categoriesRetrieve up to 100 account catalog categories, sortable by creation date.
Get catalog categoryGet a catalog category with the given category id.
Get catalog category itemsRetrieve up to 100 sorted items per request from a category using the category id.
Get catalog category relationships itemsGet all items in the given category id.
Get catalog itemGet a specific catalog item with the given item id.
Get catalog item categoriesRetrieve the catalog categories for an item by id, sorted by 'created' date, with a 100-category maximum per request.
Get catalog item relationships categoriesGet all catalog categories that a particular item is in.
Get catalog itemsRetrieve up to 100 sorted catalog items per account, with `$custom` integration and `$default` type.
Get catalog item variantsRetrieve up to 100 variants per request for a specific item id, sortable by creation date.
Get catalog variantGet a catalog item variant with the given variant id.
Get catalog variantsRetrieve up to 100 account variants per request, sortable by creation date.
Get couponGet a specific coupon with the given coupon id.
Get coupon codeReturns a coupon code specified by the given identifier.
Get coupon code bulk create jobGet a coupon code bulk create job with the given job id.
Get coupon code bulk create jobsGet all coupon code bulk create jobs.
Get coupon code relationships couponGets a list of coupon code relationships associated with the given coupon id*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `coupon-codes:read`
Get coupon codesObtains coupon codes using necessary coupon or profile filters.
Get coupon codes for couponGets a list of coupon codes associated with the given coupon id*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `coupon-codes:read`
Get coupon for coupon codeGet the coupon associated with a given coupon code id.
Get coupon relationships coupon codesGets the coupon relationship associated with the given coupon code id*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `coupons:read`
Get couponsGet all coupons in an account.
Get create categories jobGet a catalog category bulk create job with the given job id.
Get create categories jobsGet all catalog category bulk create jobs.
Get create items jobGet a catalog item bulk create job with the given job id.
Get create items jobsGet all catalog item bulk create jobs.
Get create variants jobGet a catalog variant bulk create job with the given job id.
Get create variants jobsGet all catalog variant bulk create jobs.
Get delete categories jobGet a catalog category bulk delete job with the given job id.
Get delete categories jobsGet all catalog category bulk delete jobs.
Get delete items jobGet a catalog item bulk delete job with the given job id.
Get delete items jobsGet all catalog item bulk delete jobs.
Get delete variants jobGet a catalog variant bulk delete job with the given job id.
Get delete variants jobsGet all catalog variant bulk delete jobs.
Get eventGet an event with the given event id.
Get event metricGet the metric for an event with the given event id.
Get event profileGet the profile associated with an event with the given event id.
Get event relationships metricGet a list of related metrics for an event*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `events:read` `metrics:read`
Get event relationships profileGet profile [relationships](https://developers.
Get eventsGet all events in an account requests can be sorted by the following fields: `datetime`, `timestamp` returns a maximum of 200 events per page.
Get flowGet a flow with the given flow id.
Get flow actionGet a flow action from a flow with the given flow action id.
Get flow action for messageGet the flow action for a flow message with the given message id.
Get flow action messagesRetrieve up to 50 flow messages per request by action id, sortable by various fields, with ascending/descending options, and paginated using `page[size]` and `page[number]`.
Get flow action relationships flowGet the flow associated with the given action id.
Get flow action relationships messagesRetrieves up to 50 flow message relationships per request for a specified flow action id, with cursor pagination.
Get flow flow actionsGet all flow actions associated with the given flow id.
Get flow for flow actionGet the flow associated with the given action id.
Get flow messageGet the flow message of a flow with the given message id.
Get flow message relationships actionGet the [relationship](https://developers.
Get flow message relationships templateReturns the id of the related template*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `templates:read`
Get flow message templateReturn the related template*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `templates:read`
Get flow relationships flow actionsRetrieve all flow action relationships for a specific flow id, sortable by `id`, `status`, `created`, `updated`.
Get flow relationships tagsReturn the tag ids of all tags associated with the given flow.
Get flowsGet all flows in an account.
Get flow tagsReturn all tags associated with the given flow id.
Get formGet the form with the given id.
Get form for form versionGet the form associated with the given form version.
Get form id for form versionGet the id of the form associated with the given form version.
Get formsGet all forms in an account.
Get form versionGet the form version with the given id.
Get imageGet the image with the given image id.
Get imagesGet all images in an account.
Get listApi allows 75 req/sec and 700 req/min, but with 'profile count' param, it's 1 req/sec and 15 req/min.
Get list profilesRetrieve profiles in a list by id, filterable by email/phone/push token/join date, sortable by join date.
Get list relationships profilesGet profile membership [relationships](https://developers.
Get list relationships tagsReturns the tag ids of all tags associated with the given list.
Get ListsRetrieve marketing lists from your klaviyo account.
Get list tagsReturn all tags associated with the given list id.
Get metricGet a metric with the given metric id.
Get metricsGet all metrics in an account.
Get profileGet the profile with the given profile id.
Get profile listsGet list memberships for a profile with the given profile id.
Get profile relationships listsGet list memberships for a profile with the given profile id.
Get profile relationships segmentsGet segment membership relationships for a profile with the given profile id.
Get ProfilesRetrieve profiles from your klaviyo account.
Get profile segmentsGet segment memberships for a profile with the given profile id.
Get segmentFetch a segment by id with default rates of 75/s and 700/m, or with `additional-fields` at 1/s and 15/m.
Get segment profilesRetrieve profiles in a segment by id, filtering by email, phone, token, or join date, and sorting by join date.
Get segment relationships profilesGet all profile membership [relationships](https://developers.
Get segment relationships tagsIf `related resource` is `tags`, returns the tag ids of all tags associated with the given segment id.
Get segmentsFetch segments from an account with filters like `name`, `created`, and `updated`.
Get segment tagsReturn all tags associated with the given segment id.
Get tagRetrieve the tag with the given tag id.
Get tag groupRetrieve the tag group with the given tag group id.
Get tag group relationships tagsReturns the tag ids of all tags inside the given tag group.
Get tag groupsRetrieve up to 25 tag groups per account, sortable/filterable by specific attributes.
Get tag group tagsReturn the tags for a given tag group id.
Get tag relationships campaignsReturns the ids of all campaigns associated with the given tag.
Get tag relationships flowsReturns the ids of all flows associated with the given tag.
Get tag relationships listsReturns the ids of all lists associated with the given tag.
Get tag relationships segmentsReturns the ids of all segments associated with the given tag.
Get tag relationships tag groupReturns the id of the tag group related to the given tag.
Get tagsRetrieve up to 50 account tags at once, filterable/sortable by name or id, with cursor pagination.
Get tag tag groupReturns the tag group resource for a given tag id.
Get templateGet a template with the given template id.
Get templatesRetrieve account templates with sorting options (`id`, `name`, `created`, `updated`).
Get update categories jobGet a catalog category bulk update job with the given job id.
Get update categories jobsGet all catalog category bulk update jobs.
Get update items jobGet a catalog item bulk update job with the given job id.
Get update items jobsGet all catalog item bulk update jobs.
Get update variants jobGet a catalog variate bulk update job with the given job id.
Get update variants jobsGet all catalog variant bulk update jobs.
Get version ids for formGet the ids of the form versions for the given form.
Get versions for formGet the form versions for the given form.
Get webhookGet the webhook with the given id.
Get webhooksGet all webhooks in an account.
Get webhook topicGet the webhook topic with the given id.
Get webhook topicsGet all webhook topics in a klaviyo account.
Merge profilesQueue a task to merge one source profile into a destination profile using their ids.
Query campaign valuesReturns the requested campaign analytics values data*rate limits*:burst: `1/s`steady: `2/m`daily: `225/d` **scopes:** `campaigns:read`
Query flow seriesReturns the requested flow analytics series data*rate limits*:burst: `1/s`steady: `2/m`daily: `225/d` **scopes:** `flows:read`
Query flow valuesReturns the requested flow analytics values data*rate limits*:burst: `1/s`steady: `2/m`daily: `225/d` **scopes:** `flows:read`
Query metric aggregatesThe klaviyo endpoint fetches metric events, handling json requests for custom data queries, sorting, and filtering; offers grouping and time-based filters; requires adherence to rate limits (3 requests per second, 60 per minute) under 'metrics:read'.
Remove Profile from ListRemove profiles from a klaviyo list by profile ids or email addresses.
Request profile deletionTo delete a profile, use only one identifier: email, phone number, or id.
Spawn bulk profile import jobInitiate a job to create/update a batch of profiles, up to 10,000 with a max size of 5mb per request.
Spawn coupon code bulk create jobCreate a coupon-code-bulk-create-job to bulk create a list of coupon codes.
Spawn create categories jobCreate bulk job for up to 100 catalog categories with a 5mb size limit and a max of 500 concurrent jobs.
Spawn create items jobCreate batches of up to 100 catalog items with a 5mb size limit using the bulk job, which allows 500 concurrent jobs.
Spawn create variants jobInitiate a job to bulk create up to 100 catalog variants, with a 5mb payload size limit.
Spawn delete categories jobDelete multiple catalog categories in bulk, with a limit of 100 per request and a 5mb payload size.
Spawn delete items jobDelete batches of catalog items with a bulk job, max 100 items/request, 5mb size limit, and up to 500 concurrent jobs.
Spawn delete variants jobDelete multiple catalog variants with a bulk job, max 100 per request, 5mb size limit.
Spawn update categories jobCreate a job to bulk update up to 100 categories, with a 5mb size limit and a maximum of 500 concurrent jobs.
Spawn update items jobYou can bulk update up to 100 catalog items with a 5mb payload limit.
Spawn update variants jobCreate a job to bulk update up to 100 catalog variants with a 5mb payload limit.
Subscribe profilesThe api supports double opt-in for marketing, with 'historical import' bypassing consent.
Suppress profilesSuppress profiles by email, segment, or list id to stop email marketing, regardless of consent.
Unregister client push tokenThis endpoint unsubscribes a push token, for use with klaviyo's mobile sdks and a public api key.
Unsubscribe profilesOpt-out profiles from email or sms marketing.
Unsuppress profilesRemove 'user suppressed' blocks on profiles manually via email, segment, or list id.
Update CampaignUpdate a campaign with the specified attributes.
Update campaign messageUpdate a campaign message*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:write`
Update campaign send jobPermanently cancel the campaign, setting the status to canceled or revert the campaign, setting the status back to draft*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:write`
Update catalog categoryUpdate a catalog category with the given category id.
Update catalog category relationships itemsUpdate item relationships for the given category id.
Update catalog itemUpdate a catalog item with the given item id.
Update catalog item relationships categoriesUpdate catalog category relationships for the given item id.
Update catalog variantUpdate a catalog item variant with the given variant id.
Update coupon*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `coupons:write`
Update coupon codeUpdates a coupon code specified by the given identifier synchronously.
Update flow statusUpdate the status of a flow with the given flow id, and all actions in that flow.
Update imageUpdate the image with the given image id.
Update listUpdate the name of a list with the given list id.
Update profileUpdate profiles with the provided id.
Update segmentUpdate a segment with the given segment id.
Update tagUpdate the tag with the given tag id.
Update tag groupUpdate the tag group with the given tag group id.
Update templateUpdate a template with the given template id.
Update webhookUpdate the webhook with the given id.
Upload image from fileUpload an image from a file.
Upload image from urlImport an image from a url or data uri.

What is the Composio tool router, and how does it fit here?

What is Tool Router?

Composio's Tool Router helps agents find the right tools for a task at runtime. You can plug in multiple toolkits (like Gmail, HubSpot, and GitHub), and the agent will identify the relevant app and action to complete multi-step workflows. This can reduce token usage and improve the reliability of tool calls. Read more here: Getting started with Tool Router

The tool router generates a secure MCP URL that your agents can access to perform actions.

How the Tool Router works

The Tool Router follows a three-phase workflow:

  1. Discovery: Searches for tools matching your task and returns relevant toolkits with their details.
  2. Authentication: Checks for active connections. If missing, creates an auth config and returns a connection URL via Auth Link.
  3. Execution: Executes the action using the authenticated connection.

Step-by-step Guide

Prerequisites

Before starting, make sure you have:
  • A Google API key for Gemini models
  • A Composio account and API key
  • Python 3.9 or later installed
  • Basic familiarity with Python

Getting API Keys for Google and Composio

Google API Key
  • Go to Google AI Studio and create an API key.
  • Copy the key and keep it safe. You will put this in GOOGLE_API_KEY.
Composio API Key and User ID
  • Log in to the Composio dashboard.
  • Go to Settings → API Keys and copy your Composio API key. Use this for COMPOSIO_API_KEY.
  • Decide on a stable user identifier to scope sessions, often your email or a user ID. Use this for COMPOSIO_USER_ID.

Install dependencies

bash
pip install google-adk composio-google python-dotenv

Inside your virtual environment, install the required packages.

What's happening:

  • google-adk is Google's Agents Development Kit
  • composio connects your agent to Klaviyo via MCP
  • composio-google provides the Google ADK provider
  • python-dotenv loads environment variables

Set up ADK project

bash
adk create my_agent

Set up a new Google ADK project.

What's happening:

  • This creates an agent folder with a root agent file and .env file

Set environment variables

bash
GOOGLE_API_KEY=your-google-api-key
COMPOSIO_API_KEY=your-composio-api-key
COMPOSIO_USER_ID=your-user-id-or-email

Save all your credentials in the .env file.

What's happening:

  • GOOGLE_API_KEY authenticates with Google's Gemini models
  • COMPOSIO_API_KEY authenticates with Composio
  • COMPOSIO_USER_ID identifies the user for session management

Import modules and validate environment

python
import os
import warnings

from composio import Composio
from composio_google import GoogleProvider
from dotenv import load_dotenv
from google.adk.agents.llm_agent import Agent
from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParams
from google.adk.tools.mcp_tool.mcp_toolset import McpToolset

load_dotenv()

warnings.filterwarnings("ignore", message=".*BaseAuthenticatedTool.*")

GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
COMPOSIO_API_KEY = os.getenv("COMPOSIO_API_KEY")
COMPOSIO_USER_ID = os.getenv("COMPOSIO_USER_ID")

if not GOOGLE_API_KEY:
    raise ValueError("GOOGLE_API_KEY is not set in the environment.")
if not COMPOSIO_API_KEY:
    raise ValueError("COMPOSIO_API_KEY is not set in the environment.")
if not COMPOSIO_USER_ID:
    raise ValueError("COMPOSIO_USER_ID is not set in the environment.")
What's happening:
  • os reads environment variables
  • Composio is the main Composio SDK client
  • GoogleProvider declares that you are using Google ADK as the agent runtime
  • Agent is the Google ADK LLM agent class
  • McpToolset lets the ADK agent call MCP tools over HTTP

Create Composio client and Tool Router session

python
print("Initializing Composio client...")
composio_client = Composio(api_key=COMPOSIO_API_KEY, provider=GoogleProvider())

print("Creating Composio session...")
composio_session = composio_client.create(
    user_id=COMPOSIO_USER_ID,
    toolkits=["klaviyo"],
)

COMPOSIO_MCP_URL = composio_session.mcp.url
print(f"Composio MCP HTTP URL: {COMPOSIO_MCP_URL}")
What's happening:
  • Authenticates to Composio with your API key
  • Declares Google ADK as the provider
  • Spins up a short-lived MCP endpoint for your user and selected toolkit
  • Stores the MCP HTTP URL for the ADK MCP integration

Set up the McpToolset and create the Agent

python
print("Creating Composio toolset for the agent...")
composio_toolset = McpToolset(
    connection_params=StreamableHTTPConnectionParams(
        url=COMPOSIO_MCP_URL,
        headers={"x-api-key": os.getenv("COMPOSIO_API_KEY")}
    )
)

root_agent = Agent(
    model="gemini-2.5-pro",
    name="composio_agent",
    description="An agent that uses Klaviyo tools to perform actions.",
    instruction=(
        "You are a helpful assistant connected to Composio. "
        "You have the following tools available: "
        "COMPOSIO_SEARCH_TOOLS, COMPOSIO_MULTI_EXECUTE_TOOL, "
        "COMPOSIO_MANAGE_CONNECTIONS, COMPOSIO_REMOTE_BASH_TOOL, COMPOSIO_REMOTE_WORKBENCH. "
        "Use these tools to help users with Klaviyo operations."
    ),
    tools=[composio_toolset],
)

print("\nAgent setup complete. You can now run this agent directly ;)")
What's happening:
  • Connects the ADK agent to the Composio MCP endpoint through McpToolset
  • Uses Gemini as the model powering the agent
  • Lists exact tool names in instruction to reduce misnamed tool calls

Run the agent

bash
# Run in CLI mode
adk run my_agent

# Or run in web UI mode
adk web
Execute the agent from the project root. The web command opens a web portal where you can chat with the agent. What's happening:
  • adk run runs the agent in CLI mode
  • adk web opens a web UI for interactive testing

Complete Code

Here's the complete code to get you started with Klaviyo and Google ADK:

python
import os
import warnings

from composio import Composio
from composio_google import GoogleProvider
from dotenv import load_dotenv
from google.adk.agents.llm_agent import Agent
from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParams
from google.adk.tools.mcp_tool.mcp_toolset import McpToolset

def main():
    try:
        load_dotenv()

        warnings.filterwarnings("ignore", message=".*BaseAuthenticatedTool.*")

        GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
        COMPOSIO_API_KEY = os.getenv("COMPOSIO_API_KEY")
        COMPOSIO_USER_ID = os.getenv("COMPOSIO_USER_ID")

        if not GOOGLE_API_KEY:
            raise ValueError("GOOGLE_API_KEY is not set in the environment.")
        if not COMPOSIO_API_KEY:
            raise ValueError("COMPOSIO_API_KEY is not set in the environment.")
        if not COMPOSIO_USER_ID:
            raise ValueError("COMPOSIO_USER_ID is not set in the environment.")

        print("Initializing Composio client...")
        composio_client = Composio(api_key=COMPOSIO_API_KEY, provider=GoogleProvider())

        print("Creating Composio session...")
        composio_session = composio_client.create(
            user_id=COMPOSIO_USER_ID,
            toolkits=["klaviyo"],
        )

        COMPOSIO_MCP_URL = composio_session.mcp.url
        print(f"Composio MCP HTTP URL: {COMPOSIO_MCP_URL}")

        print("Creating Composio toolset for the agent...")
        composio_toolset = McpToolset(
            connection_params=StreamableHTTPConnectionParams(
                url=COMPOSIO_MCP_URL,
                headers={"x-api-key": os.getenv("COMPOSIO_API_KEY")}
            )
        )

        root_agent = Agent(
            model="gemini-2.5-pro",
            name="composio_agent",
            description="An agent that uses Klaviyo tools to perform actions.",
            instruction=(
                "You are a helpful assistant connected to Composio. "
                "You have the following tools available: "
                "COMPOSIO_SEARCH_TOOLS, COMPOSIO_MULTI_EXECUTE_TOOL, "
                "COMPOSIO_MANAGE_CONNECTIONS, COMPOSIO_REMOTE_BASH_TOOL, COMPOSIO_REMOTE_WORKBENCH. "
                "Use these tools to help users with Klaviyo operations."
            ),
            tools=[composio_toolset],
        )

        print("\nAgent setup complete. You can now run this agent directly ;)")

    except Exception as e:
        print(f"\nAn error occurred during agent setup: {e}")

if __name__ == "__main__":
    main()

Conclusion

You've successfully integrated Klaviyo with the Google ADK through Composio's MCP Tool Router. Your agent can now interact with Klaviyo using natural language commands.

Key takeaways:

  • The Tool Router approach dynamically routes requests to the appropriate Klaviyo tools
  • Environment variables keep your credentials secure and separate from code
  • Clear agent instructions reduce tool calling errors
  • The ADK web UI provides an interactive interface for testing and development

You can extend this setup by adding more toolkits to the toolkits array in your session configuration.

How to build Klaviyo MCP Agent with another framework

FAQ

What are the differences in Tool Router MCP and Klaviyo MCP?

With a standalone Klaviyo MCP server, the agents and LLMs can only access a fixed set of Klaviyo tools tied to that server. However, with the Composio Tool Router, agents can dynamically load tools from Klaviyo and many other apps based on the task at hand, all through a single MCP endpoint.

Can I use Tool Router MCP with Google ADK?

Yes, you can. Google ADK fully supports MCP integration. You get structured tool calling, message history handling, and model orchestration while Tool Router takes care of discovering and serving the right Klaviyo tools.

Can I manage the permissions and scopes for Klaviyo while using Tool Router?

Yes, absolutely. You can configure which Klaviyo scopes and actions are allowed when connecting your account to Composio. You can also bring your own OAuth credentials or API configuration so you keep full control over what the agent can do.

How safe is my data with Composio Tool Router?

All sensitive data such as tokens, keys, and configuration is fully encrypted at rest and in transit. Composio is SOC 2 Type 2 compliant and follows strict security practices so your Klaviyo data and credentials are handled as safely as possible.

Used by agents from

Context
ASU
Letta
glean
HubSpot
Agent.ai
Altera
DataStax
Entelligence
Rolai
Context
ASU
Letta
glean
HubSpot
Agent.ai
Altera
DataStax
Entelligence
Rolai
Context
ASU
Letta
glean
HubSpot
Agent.ai
Altera
DataStax
Entelligence
Rolai

Never worry about agent reliability

We handle tool reliability, observability, and security so you never have to second-guess an agent action.