API Reference
16 MCP tools exposed by mcp-crm server. Connected AI agents discover these automatically via the MCP listTools protocol. This page is a human-readable reference and is also available as JSON at /api/tools.
Explore (1)
describe_schema
ExploreIntrospect the subset of 08Liter tables exposed by this MCP server. Use this first to learn what fields are available before calling query tools.
Parameters
| Name | Type | Req | Description |
|---|---|---|---|
| table | enum | brand | partner | partner_admin | campaign | category_brand | brand_email | partner_contract | partner_deposit_transaction. Omit for table list. |
Example
{
"table": "brand"
}Returns 20 columns including category_id, president, follow_count
Query (read 08L) (9)
list_categories
Query (read 08L)08Liter canonical category tree. Top-level: λ·°ν°(12), ν¨μ (13), λΌμ΄ν(14), μν(33), μ μ(34), μ·¨λ―Έ(35), λ°λ €λλ¬Ό(6666).
Parameters
| Name | Type | Req | Description |
|---|---|---|---|
| parentId | number | Return children of this category. Omit for top-level (parent_id=0). | |
| language | enum | ko | en | ja | cn | vi | in (default: ko) |
Example
{
"parentId": 12,
"language": "ko"
}λ·°ν° νμ μΉ΄ν κ³ λ¦¬: κΈ°λ³Έ μΌμ΄, μ€νμ μΌμ΄, ν΄λ μ§, μ μΌμ΄, ...
search_brands
Query (read 08L)Search 08Liter brands with CRM-relevant filters. Returns brand identity, category, most-recent-campaign date, and a single contactable partner_admin.
Parameters
| Name | Type | Req | Description |
|---|---|---|---|
| categoryId | number | Filter by category (use list_categories to resolve names) | |
| countryCode | string | e.g. "82" for Korea | |
| lastCampaignBefore | ISO date | Brands whose most recent campaign started before this date (dormant filter) | |
| lastCampaignAfter | ISO date | Brands whose most recent campaign started after this date (active filter) | |
| hasVerifiedContact | boolean | Require at least one verified partner_admin email (default: true) | |
| keyword | string | Substring match against brand.president or partner.name | |
| limit | number | 1-200 (default: 50) | |
| offset | number | Pagination offset (default: 0) |
Example
{
"categoryId": 12,
"lastCampaignBefore": "2025-01-01",
"hasVerifiedContact": true,
"limit": 5
}Dormant beauty brands with verified contact β the classic reactivation scenario
get_brand
Query (read 08L)Drill into a single brand: full profile, parent partner, ALL verified contacts, N most-recent campaigns, current liter balance.
Parameters
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | number | β | brand.id from search_brands |
| recentCampaignsLimit | number | 0-20 (default: 5) |
Example
{
"brandId": 13579,
"recentCampaignsLimit": 3
}Returns νκ΅νμ₯ν(μ£Ό) with 1,070,000 Liter balance, μνμ νμ₯ contact, cushion campaign history
search_partner_contacts
Query (read 08L)List ALL verified partner_admin contacts for a partner. Use when you need multiple contacts for CC or multi-recipient outreach.
Parameters
| Name | Type | Req | Description |
|---|---|---|---|
| partnerId | number | β | partner.id |
| includeInactive | boolean | Include non-READY admins (default: false) |
search_campaigns
Query (read 08L)Search 08Liter campaigns. Common status_codes: 1206=accepting, 1208=review, 1209=closed, 1210=cancelled, 1211=rejected.
Parameters
| Name | Type | Req | Description |
|---|---|---|---|
| partnerId | number | Filter by partner | |
| statusCodes | string[] | 4-char codes like ["1209"] | |
| startedAfter | ISO date | campaign.start_at after this | |
| startedBefore | ISO date | campaign.start_at before this | |
| keyword | string | Substring match on campaign name | |
| minApplyCount | number | Minimum applicants | |
| limit | number | 1-200 (default: 50) | |
| offset | number | Pagination offset (default: 0) |
Example
{
"startedAfter": "2024-10-01",
"minApplyCount": 100,
"limit": 10
}High-traction campaigns for reference when drafting outreach
get_campaign_performance
Query (read 08L)Engagement snapshot for a single campaign: raw counts plus derived ratios (fill rate, oversubscription, apply-per-view).
Parameters
| Name | Type | Req | Description |
|---|---|---|---|
| campaignId | number | β | campaign.id |
list_segments
Query (read 08L)List existing CRM segments in crm-pg. Use to discover what target lists exist before creating duplicates.
Parameters
| Name | Type | Req | Description |
|---|---|---|---|
| limit | number | 1-100 (default: 20) | |
| kind | enum | partner | brand | campaign |
list_drafts
Query (read 08L)List existing email drafts with status, target count, segment info. Use to discover campaigns in progress.
Parameters
| Name | Type | Req | Description |
|---|---|---|---|
| limit | number | 1-100 (default: 20) | |
| status | enum | draft | in_review | approved | rejected | sent | cancelled |
Author (write CRM) (2)
create_segment
Author (write CRM)Persist a named target list in crm-pg. Use after search_brands / search_campaigns to freeze results, then pass segment_id to save_message_draft.
Parameters
| Name | Type | Req | Description |
|---|---|---|---|
| name | string | β | Segment name |
| kind | enum | β | partner | brand | campaign |
| description | string | Human-readable note | |
| createdBy | string | Actor identifier | |
| targets | array | β | { externalId: number, snapshot: object }[] β each row from the search tool |
save_message_draft
Author (write CRM)Persist an AI-generated email campaign with per-target rendering. Creates draft status β NOT sent until a human approves via the review gate.
Parameters
| Name | Type | Req | Description |
|---|---|---|---|
| segmentId | string | β | From create_segment |
| name | string | β | Campaign name |
| subjectTemplate | string | β | Default subject line |
| bodyTemplate | string | β | Default body (HTML or plaintext) |
| senderName | string | From name (default: 08Liter CRM) | |
| senderEmail | string | From email (default: crm@08liter.com) | |
| createdBy | string | Actor | |
| targets | array | β | { externalId, toEmail, toName?, subject?, body?, context? }[] β per-target overrides for personalization |
Control (1)
queue_for_review
ControlHand a draft to human reviewers via the crm-web review gate. Transitions draft β in_review. The MCP server NEVER sends email; after this, reviewers approve/reject per target then click Send.
Parameters
| Name | Type | Req | Description |
|---|---|---|---|
| draftId | string | β | From save_message_draft |
| actor | string | Who queued it | |
| note | string | Context for the reviewer |
Admin (menu/page) (3)
upsert_dynamic_page
Admin (menu/page)Create or update page content at /p/{groupSlug}/{itemSlug}. Sections define layout: "text" (HTML), "stats" (metric cards), "table" (data grid). Put search_brands/search_campaigns results directly into table rows.
Parameters
| Name | Type | Req | Description |
|---|---|---|---|
| groupSlug | string | β | Menu group slug |
| itemSlug | string | β | Menu item slug |
| title | string | β | Page title |
| description | string | Subtitle | |
| createdBy | string | Actor | |
| sections | array | β | Array of section objects. Types: { type: "text", title?, content: "<html>" } | { type: "stats", title?, items: [{ label, value }] } | { type: "table", title?, columns: string[], rows: object[] } |
Example
{
"groupSlug": "crm",
"itemSlug": "dormant",
"title": "ν΄λ©΄ λΈλλ",
"sections": [
{
"type": "stats",
"items": [
{
"label": "Total",
"value": 47
}
]
},
{
"type": "table",
"columns": [
"partner_name",
"last_campaign_at"
],
"rows": []
}
]
}Creates a page with stats + table at /p/crm/dormant
Safety constraints
- No send tool β MCP never sends email.
queue_for_reviewhands off to a human reviewer. - Read-only 08L β All zeliter queries use
SET SESSION TRANSACTION READ ONLY. No INSERT/UPDATE/DELETE. - B2C blocked β
member.marketing_consentis 100% NULL. No member marketing until 08L adds a real consent mechanism. - Row cap β Every query is clamped to
MCP_MAX_ROW_LIMIT(default 1000). Response includesclamped_byif triggered. - Audit trail β Every tool call is logged to crm-pg
AuditEntry+ stderr. Viewable at /audit. - Suppression list β Bounced/unsubscribed/complained addresses in
Suppressiontable are excluded at send time.
Typical agent flow
- 1.
list_categoriesβ pick target category - 2.
search_brandsβ find dormant/active brands - 3.
get_brandβ deep-dive for personalization context - 4.
create_segmentβ save the target list - 5.
save_message_draftβ generate per-target personalized emails - 6.
queue_for_reviewβ hand off to human at/drafts/[id] - 7. Human approves/rejects per target, clicks Send β dry_run or SendGrid