# MCP Classification

> Creates AI-powered classification and data processing magic columns in Leadspicker projects through the Leadspicker MCP server, using GPT-4o-Mini behind the scenes. Use whenever the user wants to classify, score, label, tag, clean, or transform contact / company data in Leadspicker — for example "classify companies as SaaS", "is this person a decision maker", "determine company industry", "clean job titles", "create an icebreaker from LinkedIn posts", "is the company B2B or B2C", "classify leads as relevant", "chci klasifikovat firmy", "urči odvětví", "vyčisti název firmy", "je ten člověk relevantní", or any request to add an AI-powered magic column. Triggers on AI classification, lead scoring, contact tagging, data cleaning, or personalization columns in the context of Leadspicker.

- Skill: `tomasblatak/mcp-classification` (Agent Skill)
- Install (CLI): `npx skillmds@latest add tomasblatak/mcp-classification`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomasblatak/mcp-classification/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: tomasblatak (https://skillmd.com/u/tomasblatak)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/tomasblatak/mcp-classification

---


# Leadspicker AI Classifier (MCP)

Creates AI-powered magic columns in Leadspicker projects through the Leadspicker MCP server.
Each column runs GPT-4o-Mini on every contact in the project to classify, categorize, clean,
or generate text content.

This skill is a companion to **mcp-data-enrichment** — it consumes the enriched data
(company descriptions, website summaries, job titles, LinkedIn profiles) as input variables.

---

## MCP tools used

| MCP tool                              | Purpose                                                                                                                                                               |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `mcp__leadspicker__list_projects`     | Look up project by name (`search_query`) or list recent (`order_by="last_active"`)                                                                                    |
| `mcp__leadspicker__get_project`       | Fetch project detail by `project_id`                                                                                                                                  |
| `mcp__leadspicker__list_contacts`     | Fetch contact rows for context (`page=1, page_size=5` for previews)                                                                                                   |
| `mcp__leadspicker__preview_ai_prompt` | Submit a prompt for preview (first 5 rows) and fetch results. Parameters: `project_id`, `prompt`, `column_name`, `is_boolean`, `magic_column_type="ai_custom_column"` |
| `mcp__leadspicker__enrich_contacts`   | Launch full classification on every contact. Parameters: `project_id`, `magic_column_type="ai_custom_column"`, `column_name`, `prompt`, `is_boolean`                  |

---

## User input

| Parameter              | Description                                   | Example                     |
| ---------------------- | --------------------------------------------- | --------------------------- |
| `project_id`           | Target Leadspicker project (resolved by name) | `29841`                     |
| Classification request | What to classify or generate                  | `"Is this a SaaS company?"` |
| `column_name`          | New column name                               | `"Is SaaS"`                 |

### Project resolution

**Display format:** always render projects as **`{name} (#{id})`** — name first, ID in parentheses.

1. **User named a project** → `mcp__leadspicker__list_projects(search_query="{name}", limit=5)`. Confirm match; if multiple, ask which one.
2. **User did not name a project** → `mcp__leadspicker__list_projects(order_by="last_active", limit=20)` and ask the user to pick.

If the user did not provide `column_name`, generate a clear short name from the
classification goal (e.g. "Is SaaS Company", "Industry", "Relevant Decision Maker").

---

## System prompt — fixed, do not modify

Every AI column in Leadspicker is wrapped by a fixed server-side system prompt that you
**cannot change**. It forces GPT-4o-Mini to output strict JSON.

**Boolean mode** (`is_boolean=True`):

```
Server forces: {"result": true | false, "message": "A short explanation."}
```

**String mode** (`is_boolean=False`):

```
Server forces: {"result": "response"}
```

**Implications for your prompt:**

- NEVER ask GPT to output `yes/no`, `classification: yes/no`, or any custom JSON shape.
- NEVER include output-format instructions — the system prompt already enforces them.
- Just describe the task, criteria, and input variables.
- For boolean: GPT returns `true`/`false` plus a short `message`.
- For string: GPT returns a free-text value in `result`.

---

## Output mode decision

Decide based on the user's question:

**Use `is_boolean=True` when the answer is yes/no:**

- "Is this a SaaS company?"
- "Is this person a decision maker?"
- "Is this company B2B?"
- "Is this lead relevant for our outreach?"
- "Does this company target enterprise?"

Best for filtering where you only need a true/false flag.

**Use `is_boolean=False` (string) when the answer is a value, label, or text:**

- "What industry is this company in?"
- "Clean the job title"
- "Write an icebreaker from LinkedIn posts"
- "Clean the first name"
- "Classify as B2B or B2C" (multiple categories, not yes/no)
- "Summarize the LinkedIn post"
- "What department does this person belong to?"

**Use `is_boolean=False` (string) with scored format for nuanced decisions:**

Format: `"Yes | score | reasoning"` or `"No | score | reasoning"`. Useful when the user
wants confidence + reasoning in one column (e.g. filter rows by score ≥ 7), or when the
classification has many borderline cases.

**Rule of thumb:** Simple filtering → boolean. Multiple categories or free text → string.
Complex yes/no with confidence → string scored.

---

## Smart variable selection

Pick only the variables relevant to the classification. Don't dump all variables into every
prompt — keep it lean so GPT-4o-Mini focuses on what matters.

### Company classification

For company-level classification (industry, B2B/B2C, SaaS, agency, …):

```
Input:
- Company Name: {{company_name}}
- Company Website: {{company_website}}
- LinkedIn Company Description: {{linkedin_company_description}}
- Company Website Summary: {{website_text_summary}}
```

### Person classification — basic

For job-title relevance (CEO, decision maker, role match):

```
Input:
- Position: {{position}}
```

### Person classification — detailed

For deeper person analysis (experience, background, skills):

```
Input:
- Position: {{position}}
- LinkedIn About Me: {{linkedin_about_me}}
- Present Positions Summary: {{present_experiences}}
- Past Positions Summary: {{past_experiences}}
```

### Mixed (person + company)

For "is this person a relevant lead at a SaaS company?":

```
Input:
- Position: {{position}}
- Company Name: {{company_name}}
- LinkedIn Company Description: {{linkedin_company_description}}
- Company Website Summary: {{website_text_summary}}
```

### How to pick

| User asks about...                     | Variable set    | Example                                         |
| -------------------------------------- | --------------- | ----------------------------------------------- |
| Company type, industry, business model | Company         | "Is this a SaaS company?"                       |
| Job title match, role relevance        | Person basic    | "Is this a C-level executive?"                  |
| Person background, experience fit      | Person detailed | "Has this person worked in sales leadership?"   |
| Lead relevance (person + company fit)  | Mixed           | "Is this a relevant lead for our SaaS product?" |
| Name cleaning                          | Single variable | `{{full_name}}`, `{{linkedin}}`                 |
| Job title cleaning                     | Single variable | `{{position}}`                                  |
| Company name cleaning                  | Single variable | `{{company_name}}`                              |
| Icebreaker from posts                  | Single variable | `{{linkedin_latest_posts}}`                     |
| Post summarization                     | Single variable | `{{linkedin_latest_posts}}`                     |

---

## Prompt-writing guidelines for GPT-4o-Mini

### Structure

```
1. Task — one clear sentence stating what to do
2. Criteria / rules — specific conditions, definitions, IS / IS NOT examples
3. Input variables — the Leadspicker template variables
```

### Best practices

- **Be direct and specific.** Bad: "Try to figure out what kind of company this is." Good: "Determine the primary industry of the company."
- **Define boundaries.** For boolean classifications, always state what IS and what IS NOT the target category.
- **Keep prompts concise.** GPT-4o-Mini works best with shorter prompts. Aim for 50–150 words.
- **Use simple language.** Short sentences, clear logic.
- **List acceptable values for string mode.** Explicitly enumerate all valid outputs when classifying into categories.
- **Handle missing data.** Boolean: "If there is not enough data to decide, return false." String: "If there is not enough data, return empty string."
- **One task per prompt.** Each AI column does one thing. Don't combine classification + cleaning in a single prompt.

### Do NOT

- Do NOT include output-format instructions (system prompt enforces JSON).
- Do NOT ask for `classification: yes/no` or `score: 1-10` in the output (conflicts with system prompt).
- Do NOT write multi-step instructions with numbered output fields.
- Do NOT include JSON examples in the prompt.
- Do NOT use the phrase "Respond in this exact format".
- Do NOT write prompts in Czech / Polish / etc. — always write in **English** (GPT-4o-Mini performs best in English). Vocative output is the exception (see mcp-personalizer).

---

## Prompt examples

### Company: Is SaaS? (boolean)

**`column_name`: `Is SaaS`** &nbsp;·&nbsp; **`is_boolean=True`**

```
Determine whether this company is a SaaS (Software as a Service) company.

A SaaS company primarily sells software delivered via the cloud on a subscription or recurring basis. This includes B2B SaaS platforms, productivity tools, CRMs, ERPs, developer tools, analytics platforms, and similar products where the core offering is cloud-hosted software.

Do NOT classify as SaaS: marketing agencies, consultancies, IT service providers, e-commerce stores, hardware companies, marketplaces (unless their core product is a software platform), or companies that simply use SaaS tools but sell something else.

If there is not enough information to determine, return false.

Input:
- Company Name: {{company_name}}
- Company Website: {{company_website}}
- LinkedIn Company Description: {{linkedin_company_description}}
- Company Website Summary: {{website_text_summary}}
```

### Company: Industry (string, list of categories)

**`column_name`: `Industry`** &nbsp;·&nbsp; **`is_boolean=False`**

```
Determine the primary industry of this company.

Classify into exactly one of these industries: SaaS, E-commerce, FinTech, HealthTech, EdTech, Marketing Agency, Consulting, Manufacturing, Retail, Media, Real Estate, Logistics, Cybersecurity, HR Tech, Legal Tech, Other.

Return only the industry name, nothing else. Use the exact spelling from the list above. If there is not enough data to determine the industry, return "Other".

Input:
- Company Name: {{company_name}}
- Company Website: {{company_website}}
- LinkedIn Company Description: {{linkedin_company_description}}
- Company Website Summary: {{website_text_summary}}
```

### Company: B2B or B2C (string)

**`column_name`: `B2B/B2C`** &nbsp;·&nbsp; **`is_boolean=False`**

```
Determine whether this company primarily operates as B2B (sells to other businesses) or B2C (sells to consumers).

Return exactly one of: "B2B", "B2C", or "Both". If there is not enough data, return "B2B".

Input:
- Company Name: {{company_name}}
- Company Website: {{company_website}}
- LinkedIn Company Description: {{linkedin_company_description}}
- Company Website Summary: {{website_text_summary}}
```

### Company: Targets enterprise? (boolean)

**`column_name`: `Targets Enterprise`** &nbsp;·&nbsp; **`is_boolean=True`**

```
Determine whether this company primarily targets enterprise customers (large organizations with 500+ employees).

Evidence of enterprise focus: enterprise pricing tiers, mentions of Fortune 500 / Global 2000 clients, SOC2 / ISO / GDPR certifications, dedicated enterprise sales teams, SSO / SAML support, custom contracts, or case studies featuring large corporations.

Do NOT classify as enterprise-focused if the company only serves SMBs, startups, or individual consumers, even if they mention one or two large clients.

If there is not enough information to determine, return false.

Input:
- Company Name: {{company_name}}
- Company Website: {{company_website}}
- LinkedIn Company Description: {{linkedin_company_description}}
- Company Website Summary: {{website_text_summary}}
```

### Company: Is sales tech? — scored with reasoning (string)

**`column_name`: `Is Sales Tech`** &nbsp;·&nbsp; **`is_boolean=False`**

Use this pattern whenever the user wants yes/no + confidence + reasoning in one column.

```
Determine whether this company operates in the sales technology (Sales Tech) space, rate your confidence on a scale of 1-10, and provide a one-sentence reasoning.

A Sales Tech company builds or sells technology products that help sales teams sell more effectively. This includes: CRM platforms, sales engagement tools, outreach automation, lead generation software, sales intelligence, pipeline management, revenue operations tools, conversation intelligence, sales enablement platforms, CPQ (configure-price-quote) software, and prospecting tools.

Do NOT classify as Sales Tech: companies that simply use sales tools internally, marketing-only platforms (unless they directly serve sales teams), general business consulting, recruitment platforms, or e-commerce stores.

Return your answer in this exact format: "Yes | score | reasoning" or "No | score | reasoning" where score is a number from 1 (very uncertain) to 10 (absolutely certain), and reasoning is one sentence explaining your decision.

Examples: "Yes | 9 | Company builds a sales engagement platform for outreach automation.", "No | 7 | Company is a marketing agency that does not build sales technology."

If there is not enough information, return "No | 1 | Not enough data to determine."

Input:
- Company Name: {{company_name}}
- Company Website: {{company_website}}
- LinkedIn Company Description: {{linkedin_company_description}}
- Company Website Summary: {{website_text_summary}}
```

**Scored classification template (reusable):**

```
Determine whether [GOAL], rate your confidence on a scale of 1-10, and provide a one-sentence reasoning.

[CRITERIA — what IS and what IS NOT the target]

Return your answer in this exact format: "Yes | score | reasoning" or "No | score | reasoning" where score is a number from 1 (very uncertain) to 10 (absolutely certain), and reasoning is one sentence explaining your decision.

Examples: "Yes | 9 | [example]", "No | 7 | [example]"

If there is not enough information, return "No | 1 | Not enough data to determine."

Input:
[relevant variables]
```

### Person: relevant decision maker? (boolean)

**`column_name`: `Is Decision Maker`** &nbsp;·&nbsp; **`is_boolean=True`**

```
Determine whether this person holds a decision-making position.

A decision maker is someone with authority to approve purchases or strategic initiatives. This includes: CEO, CTO, COO, CFO, CMO, VP, Director, Head of Department, Partner, Founder, Co-Founder, Owner, General Manager, Managing Director.

Do NOT classify as decision maker: individual contributors, specialists, analysts, coordinators, assistants, interns, or junior roles even if they have inflated titles.

If there is not enough information to determine, return false.

Input:
- Position: {{position}}
```

### Person: relevant for outreach — detailed (boolean)

**`column_name`: `Is Relevant Lead`** &nbsp;·&nbsp; **`is_boolean=True`**

Customize the criteria section for the user's persona / offer.

```
Determine whether this person is a relevant lead for outreach selling a B2B sales automation tool.

A relevant lead meets ALL of these criteria:
1. Works in sales, business development, revenue operations, or growth
2. Holds a manager-level position or above (Manager, Director, VP, Head of, C-level)
3. Has experience with sales teams or pipeline management

A person is NOT relevant if they: work in unrelated departments (engineering, design, HR), hold junior or individual contributor roles, or work in a completely different field.

If there is not enough information to determine, return false.

Input:
- Position: {{position}}
- LinkedIn About Me: {{linkedin_about_me}}
- Present Positions Summary: {{present_experiences}}
- Past Positions Summary: {{past_experiences}}
```

### Data cleaning: clean first name (string)

**`column_name`: `Clean First Name`** &nbsp;·&nbsp; **`is_boolean=False`**

```
Extract and clean the first name from the input for use in cold email campaigns.

Rules:
- Extract only the first name (e.g., "Ing. Vlastimil Vodicka" → "Vlastimil")
- Remove all titles, degrees, emojis, special characters, and extra spaces
- Return the name in title case (first letter uppercase, rest lowercase)
- If the full name is missing or unrecognizable, try to extract the first name from the LinkedIn URL handle (e.g., linkedin.com/in/trinahymes → "Trina")
- If no name can be determined, return empty string

Input:
- Full Name: {{full_name}}
- LinkedIn: {{linkedin}}
```

### Data cleaning: clean company name (string)

**`column_name`: `Clean Company Name`** &nbsp;·&nbsp; **`is_boolean=False`**

```
Clean the company name for use in cold email campaigns.

Remove all legal suffixes and unnecessary additions: LTD, LLC, Limited, GmbH, s.r.o., a.s., Inc, Corp, Corporation, Limited Liability Company, and similar. Also remove special characters, bullet points, taglines, and slogans that are appended to the name.

Return the clean company name in title case. If the name is already clean, return it as-is.

Examples: "Promoly LTD" → "Promoly", "GOOGLE LLC" → "Google", "Fitune • Fitness & Wellness Software" → "Fitune"

Input:
- Company Name: {{company_name}}
```

### Data cleaning: clean job title (string)

**`column_name`: `Clean Job Title`** &nbsp;·&nbsp; **`is_boolean=False`**

```
Clean the job title by removing unnecessary additions that people often include.

Remove: hiring announcements ("We're Hiring", "Hiring!"), personal branding slogans, emojis, hashtags, pipe separators with promotional text, and any text after "at" or "@" (company names).

Keep the core job title and its responsibility level intact. Make it concise without changing the seniority or function.

Example: "CEO || We're Hiring" → "CEO", "Senior Dev 🚀 | Building the future" → "Senior Dev"

Input:
- Position: {{position}}
```

### Personalization: icebreaker from LinkedIn posts (string)

**`column_name`: `Icebreaker`** &nbsp;·&nbsp; **`is_boolean=False`**

```
Write a personalized icebreaker sentence for a cold email based on the person's latest LinkedIn post.

Rules:
- Start with "I noticed"
- If the input is a personal post, use "I noticed on your LinkedIn..."
- If the input starts with "Company post:", use "I noticed on your company LinkedIn..."
- Focus on business-related content (product launches, insights, industry opinions). Skip personal posts about vacations, birthdays, etc.
- Keep the output under 15 words
- The icebreaker should feel natural and not salesy

This sentence will be followed by: "...and thought it might be valuable to connect" — so your output is only the first part starting with "I noticed".

If the input is empty or has no meaningful content, return empty string.

Input:
- LinkedIn Latest Posts: {{linkedin_latest_posts}}
```

> For multi-language openers (Czech salutation, Polish vocative, German formal address), use the **mcp-personalizer** skill — it has language-specific templates and grammar rules.

---

## Workflow

### Step 1 — collect input

Resolve the project (see **Project resolution**) and gather the classification request.
If the user did not provide a `column_name`, generate one from the goal.

### Step 2 — determine type

1. **What is being classified?** Company, Person, or Mixed
2. **What output mode?** Boolean / String / String scored
3. **Which variables?** Pick from **Smart variable selection**

### Step 3 — write the prompt

Follow the **Structure** and **Best practices** above:

1. Clear task definition
2. Specific criteria with IS / IS NOT
3. Fallback for missing data
4. Input variables (only relevant ones)

Do NOT include output-format instructions — the system prompt handles JSON.

### Step 4 — show the prompt to the user

Before any tool call, show the user:

- `column_name`
- `is_boolean` setting
- The full prompt text

Ask for approval.

### Step 5 — preview on first 5 rows

Always run a preview before launching the full classification — lets the user verify the
prompt before applying it to all contacts.

```
mcp__leadspicker__preview_ai_prompt(
    project_id=29841,
    column_name="Is SaaS",
    prompt="Determine whether this company is a SaaS company.\n\n…\n\nInput:\n- Company Name: {{company_name}}\n…",
    is_boolean=True,
    magic_column_type="ai_custom_column",
)
```

The preview tool submits the prompt and (after a short delay) returns results for the first
5 rows. While that processes, fetch contact data for context:

```
mcp__leadspicker__list_contacts(project_id=29841, page=1, page_size=5)
```

Returns `items[]` where each item has `contact_data` with `full_name`, `position`,
`linkedin`, `company_linkedin`, `company_website`, `company_name`, etc.

Show the user a combined table:

```
Preview (first 5 rows):

| Name      | Position | Company | Result      |
|-----------|----------|---------|-------------|
| John Doe  | CEO      | Acme    | SaaS        |
| Jane Smith| CTO      | Shop Co | E-commerce  |
…

Does this look correct? Should I launch the full classification?
```

If the user wants changes → adjust the prompt and re-preview.
If the user cancels → stop.

### Step 6 — launch full classification

Only after the user approves the preview:

```
mcp__leadspicker__enrich_contacts(
    project_id=29841,
    magic_column_type="ai_custom_column",
    column_name="Is SaaS",
    prompt="<same as previewed>",
    is_boolean=True,
)
```

Report success or failure.

### Step 7 — report and suggest next steps

- Confirm the column was created and is processing all contacts (asynchronous, minutes).
- Suggest related classifications:
  - After industry → "Want to also classify B2B vs B2C?"
  - After SaaS check → "Want to check if they target enterprise?"
  - After decision maker → "Want a personalized icebreaker (mcp-personalizer)?"

---

## Batch mode

When the user wants multiple classifications at once:

1. List all requested columns with names, `is_boolean`, and prompts
2. Show all prompts in one overview for approval
3. After approval, call `mcp__leadspicker__enrich_contacts` sequentially with ≈1 s delay between calls
4. Report summary: how many succeeded / failed and the column names

---

## Natural language → classification matching

| User says...                                    | Type                   | `is_boolean` | Variable set                    |
| ----------------------------------------------- | ---------------------- | ------------ | ------------------------------- |
| "Is this a SaaS company?"                       | Company boolean        | `True`       | Company                         |
| "Is this sales tech, with score and reasoning?" | Company scored string  | `False`      | Company                         |
| "Classify with confidence level"                | Scored string          | `False`      | Depends on context              |
| "What industry?"                                | Company string         | `False`      | Company                         |
| "B2B or B2C?"                                   | Company string         | `False`      | Company                         |
| "Is this an agency?"                            | Company boolean        | `True`       | Company                         |
| "Does it target enterprise?"                    | Company boolean        | `True`       | Company                         |
| "Is this person relevant?"                      | Person boolean         | `True`       | Person basic / detailed         |
| "Is this a decision maker?"                     | Person boolean         | `True`       | Person basic                    |
| "Clean the job title"                           | Cleaning string        | `False`      | `{{position}}`                  |
| "Clean the first name"                          | Cleaning string        | `False`      | `{{full_name}}`, `{{linkedin}}` |
| "Clean company name"                            | Cleaning string        | `False`      | `{{company_name}}`              |
| "Write an icebreaker"                           | Personalization string | `False`      | `{{linkedin_latest_posts}}`     |
| "Summarize LinkedIn post"                       | Personalization string | `False`      | `{{linkedin_latest_posts}}`     |
| "Czech vocative first name"                     | Localization string    | `False`      | (use mcp-personalizer)          |

---

## Common errors

| Symptom            | Likely cause                         | Fix                                                                   |
| ------------------ | ------------------------------------ | --------------------------------------------------------------------- |
| Tool returns `404` | Wrong project                        | Re-list via `mcp__leadspicker__list_projects` and reconfirm           |
| Tool returns `400` | Malformed body or invalid type       | Check `magic_column_type="ai_custom_column"` and `is_boolean` boolean |
| Tool returns `422` | Column with that name already exists | Use a different `column_name`                                         |
| Tool returns `429` | Rate limit                           | Increase delay between calls to 2–3 s                                 |

---

## Safety

- Always show the prompt to the user before previewing or launching.
- Always preview before launching full classification.
- Write all prompts in English for best GPT-4o-Mini performance (vocative output is the only exception — see mcp-personalizer).

