mcpField
A
audience-builder

audience-builder

github.com/lyticsMarketing & growth449 installsUpdated 3w ago
Repository

About audience-builder

audience-builder turns a specific natural-language audience description into a validated, sized segment proposal and creates it after confirmation. It is for authenticated Lytics API users and combines schema discovery, FilterQL construction, validation, and size estimation.

Key features

  1. 01Parse audience criteria
  2. 02Discover matching schema fields
  3. 03Build and validate FilterQL
  4. 04Estimate segment size
  5. 05Request confirmation before creation

Use cases

  1. 01Create a segment from specific audience criteria
  2. 02Review audience size before creating a segment
  3. 03Update an existing segment with proposed filter changes

MCP support

The input does not describe an MCP connection or MCP-specific behavior.

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/lytics/agent-skills --skill audience-builder

After installing, type/audience-builderin Claude Code to confirm it loaded.

Details

From the project README

Audience Builder

Purpose

The primary end-to-end skill. Takes a natural language audience description and produces a validated, sized, and confirmed segment. Composes schema-discovery, filterql-builder, segment-manager, and confirmation-gate.

Environment

Requires authenticated API access. See ../references/auth.md for credential resolution.

Inputs

  • Natural language description of the desired audience
  • Optional: segment name, table (default: user), kind (default: segment), tags

End-to-End Flow

Step 0: Check if Advisor Would Be Better

If the user's request is goal-oriented rather than specific (e.g., "I want to drive more conversions" vs "US users who visited 5+ times"), suggest starting with the audience-advisor skill first:

"It sounds like you have a business goal in mind. Would you like me to analyze your data first to recommend the best targeting strategy? I can look at ML models, field distributions, and existing segments to suggest evidence-based filters."

If the user has a specific audience description, proceed directly to Step 1.

Step 1: Parse Intent

Extract the key concepts from the natural language description:

  • Target attributes (demographics, behaviors, properties)
  • Inclusion criteria (what they have/did)
  • Exclusion criteria (what they lack/didn't do)
  • Temporal constraints (time-based conditions)

Example: "US customers who haven't purchased socks in over a year"

  • Attribute: country = US
  • Exclusion: no sock purchases
  • Temporal: over 1 year ago
Step 2: Schema Discovery

Use schema-discovery skill to find matching fields:

# Get all fields to find candidates
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/user/field" \
  -H "Authorization: ${LYTICS_API_TOKEN}"

Score candidate fields by name match, type compatibility, and value distribution. For the example:

  • "US customers" -> look for: country, geo_country, country_code (string type)
  • "purchased socks" -> look for: products_purchased (set), purchase_categories (set), last_purchase_date (date)

Fetch value suggestions for top candidates -- the q parameter is required:

curl -s "${LYTICS_API_URL:-https://api.lytics.io}/api/schema/user/fieldsuggest/${FIELD}?q=${QUERY}" \
  -H "Authorization: ${LYTICS_API_TOKEN}"

Example: /api/schema/user/fieldsuggest/country?q=US

Confirm field values match (e.g., country contains "US", products_purchased contains "socks").

Step 3: Build FilterQL

Use filterql-builder skill to construct the filter expression.

Map each concept to a FilterQL condition based on field type (see ../references/field-types.md):

  • String equality: country = "US"
  • Set non-membership: NOT products_purchased INTERSECTS ("socks")
  • Date comparison: last_sock_purchase < "now-1y"

Compose with AND/OR:

FILTER AND (
  country = "US",
  NOT products_purchased INTERSECTS ("socks")
) FROM user ALIAS us_no_socks
Step 4: Validate FilterQL
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/api/segment/validate" \
  -H "Authorization: ${LYTICS_API_TOKEN}" \
  -H "Content-Type: text/plain" \
  -d 'FILTER AND (country = "US", NOT products_purchased INTERSECTS ("socks")) FROM user ALIAS us_no_socks'

If validation fails:

  1. Parse the error message
  2. Identify the syntax issue
  3. Fix the FilterQL
  4. Retry (max 3 attempts)
  5. If still failing, show the error and ask the user for guidance
Step 5: Estimate Size
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/api/segment/size" \
  -H "Authorization: ${LYTICS_API_TOKEN}" \
  -H "Content-Type: text/plain" \
  -d 'FILTER AND (country = "US", NOT products_purchased INTERSECTS ("socks")) FROM user ALIAS us_no_socks'
Step 6: Present Draft (Confirmation Gate)

Show the user a complete summary before creating:

## Proposed Audience: US Non-Sock Buyers

**Name**: US Non-Sock Buyers
**Slug**: us_no_socks
**Table**: user
**Kind**: segment

**Description**: US customers who have not purchased socks

**Field Mapping**:
- "US customers" -> `country = "US"` (field type: string, sample values: US, CA, UK)
- "haven't purchased socks" -> `NOT products_purchased INTERSECTS ("socks")` (field type: []string)

**FilterQL**:
FILTER AND (country = "US", NOT products_purchased INTERSECTS ("socks")) FROM user ALIAS us_no_socks

**Estimated Size**: ~45,000 profiles

Then show the raw API payload:

{
  "name": "US Non-Sock Buyers",
  "slug_name": "us_no_socks",
  "description": "US customers who have not purchased socks",
  "segment_ql": "FILTER AND (country = \"US\", NOT products_purchased INTERSECTS (\"socks\")) FROM user ALIAS us_no_socks",
  "kind": "segment",
  "table": "user",
  "is_public": true,
  "save_hist": true,
  "tags": []
}

Ask for confirmation: "Proceed with creating this segment? (yes/no)"

Step 7: Execute on Approval
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/v2/segment" \
  -H "Authorization: ${LYTICS_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{ ... approved payload ... }'

Report the result:

Successfully created segment "US Non-Sock Buyers" (id: abc123)
View at: ${LYTICS_API_URL}/segment/us_no_socks

After successful creation, offer an audience snapshot: "Segment created successfully. Would you like to see an audience snapshot showing the demographic breakdown and field distributions?" If yes, invoke the audience-snapshot skill with the new segment ID.

Handling Ambiguity

When field mapping is ambiguous (multiple equally strong candidates):

  1. Present the top candidates with sample values
  2. Let the agent pick the best match based on context -- do NOT prompt the user unless truly ambiguous
  3. Only ask the user when there's a genuine tie or the field purpose is unclear

Updating Existing Segments

If the user wants to update an existing segment:

  1. Fetch the current segment: GET /v2/segment/${ID}?inline=true
  2. Show current FilterQL and proposed changes
  3. Use PUT /v2/segment/${ID} instead of POST

Error Handling

  • No matching fields: Report clearly, suggest the user describe their data differently
  • Validation failure after 3 retries: Show the FilterQL and error, ask for help
  • Empty segment (size 0): Warn and suggest broadening criteria
  • Very large segment (>90% of total): Note this and confirm intent

Dependencies

  • Composes: schema-discovery skill, filterql-builder skill, segment-manager skill, ../references/confirmation-gate.md
  • References: ../references/auth.md, ../references/filterql-grammar.md, ../references/field-types.md

Comments

Markdown supported