affinity-mcp-workflows

Use when working with Affinity CRM via MCP tools - find entities, manage workflows, log interactions, prepare briefings, find warm intros. Also use when user mentions "pipeline", "deals", "relationship strength", or wants to prepare for meetings.

16 stars

Best use case

affinity-mcp-workflows is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Use when working with Affinity CRM via MCP tools - find entities, manage workflows, log interactions, prepare briefings, find warm intros. Also use when user mentions "pipeline", "deals", "relationship strength", or wants to prepare for meetings.

Teams using affinity-mcp-workflows should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/affinity-mcp-workflows/SKILL.md --create-dirs "https://raw.githubusercontent.com/diegosouzapw/awesome-omni-skill/main/skills/cli-automation/affinity-mcp-workflows/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/affinity-mcp-workflows/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How affinity-mcp-workflows Compares

Feature / Agentaffinity-mcp-workflowsStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Use when working with Affinity CRM via MCP tools - find entities, manage workflows, log interactions, prepare briefings, find warm intros. Also use when user mentions "pipeline", "deals", "relationship strength", or wants to prepare for meetings.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Affinity MCP Workflows

This skill covers the xaffinity MCP server tools, prompts, and resources for working with Affinity CRM.

## Prerequisites

The MCP server requires the xaffinity CLI to be installed:

```bash
pip install "affinity-sdk[cli]"
```

The CLI must be configured with an API key before the MCP server will work.

## ⚠️ REQUIRED WORKFLOW - Do Not Skip Steps

**You MUST complete steps 1-2 before running ANY queries or commands.**

Skipping these steps leads to incorrect or inefficient queries because:
- Command syntax may have changed since this skill was written
- New flags (like `--with-interaction-dates`) may exist that you don't know about
- You may use deprecated syntax that returns incomplete data
- The data model has nuances (e.g., `list export` vs `company ls`) that you'll miss

### Mandatory Pre-Flight Checklist

**Before proceeding to execute any commands:**

1. ✅ Read `xaffinity://data-model` using `read-xaffinity-resource`
2. ✅ Run `discover-commands` for your specific task
3. ✅ State what you learned from each step before continuing

**Example:**
```
"I read the data-model resource and learned that list entries have custom fields
accessed via fields.<Name>. I ran discover-commands for 'interaction' and found
that interaction ls supports --type all to fetch all types in one call, and
--days to limit the time range. Now I'll proceed with..."
```

## IMPORTANT: Write Operations Only After Explicit User Request

**Only use tools or prompts that modify CRM data when the user explicitly asks to do so.**

Write operations include:
- **Tools**: `execute-write-command`
- **Prompts**: `log-interaction-and-update-workflow`, `change-status`, `log-call`, `log-message`

Read-only operations (search, lookup, briefings) can be used proactively to help the user. But never create, update, or delete CRM records unless the user specifically requests it.

## Full Scan Protection

The MCP gateway enforces pagination limits to prevent unbounded data scans:

| Limit | Value | Description |
|-------|-------|-------------|
| Default | 1000 records | Applied when no `--max-results` specified |
| Maximum | 10000 records | Higher values are capped with a warning |
| `--all` flag | **BLOCKED** | Use `--max-results` or cursor pagination instead |

**Affected commands:** `list export`, `list ls`, `person ls`, `company ls`, `opportunity ls`, `note ls`, `reminder ls`, `interaction ls`, `field history`

**To fetch more than 10000 records:** Use cursor pagination with `--cursor` flag.

## Available Tools

### CLI Gateway (Primary Interface)

The CLI Gateway provides full access to the xaffinity CLI:

| Tool | Use Case |
|------|----------|
| `discover-commands` | Search CLI commands by keyword (e.g., "create person", "export list") |
| `execute-read-command` | Execute read-only CLI commands (get, search, list, export) |
| `execute-write-command` | **(write)** Execute write CLI commands (create, update, delete) |

**Usage pattern:**

1. **Discover** the right command: `discover-commands(query: "create person", category: "write")`
2. **Execute** it: `execute-write-command(command: "person create", argv: ["--first-name", "John", "--last-name", "Doe"])`

### Utility Tools

| Tool | Use Case |
|------|----------|
| `get-entity-dossier` | Comprehensive entity info (details, relationship strength, interactions, notes, list memberships) |
| `read-xaffinity-resource` | Access dynamic resources via `xaffinity://` URIs |

### Destructive Commands

Commands that delete data require double confirmation:

1. **Look up the entity first** using `execute-read-command` to show what will be deleted
2. **Ask the user in your response** by showing them the entity details and requesting confirmation
3. **Wait for user's next message** - do NOT proceed until they explicitly confirm
4. **Only after user confirms** should you execute with `confirm: true`

Example flow:
```
User: "Delete person 123"
You: execute-read-command(command: "person get", argv: ["123"])
You: "This will permanently delete John Smith (ID: 123, email: john@example.com).
      Type 'yes' to confirm deletion."
[Stop here and wait for user's response]

User: "yes"
You: execute-write-command(command: "person delete", argv: ["123"], confirm: true)
```

## Query vs CLI Commands: When to Use What

**Use `query` tool for:**
- Any operation needing **relationships** (persons at a company, companies for a person)
- Any operation needing **computed data** (interaction dates, unreplied messages)
- **Pipeline analysis** with aggregations or groupBy
- **Complex filtering** with AND/OR conditions
- **List entry operations** that need associated entities

**Use individual CLI commands for:**
- **Simple lookups**: `person get 123`, `company get 456`
- **Quick searches**: `person ls --query "John"`, `company ls --query "Acme"`
- **Metadata**: `list ls`, `field ls --list-id <id>`
- **Write operations**: All creates, updates, deletes

### Query Examples (Preferred for Complex Operations)

⚠️ **STOP: Did you complete the pre-flight checklist?** The syntax below may be outdated. Run `discover-commands` first to verify current syntax and available flags.

⚠️ **For queries with `expand` or `include`, ALWAYS use `dryRun: true` first** to see estimated API calls. These cause N+1 API calls (one per record) and can be slow or timeout.

```json
// STEP 1: Preview any expand/include query with dryRun first
{"query": {"from": "listEntries", "where": {"path": "listName", "op": "eq", "value": "Dealflow"}, "expand": ["interactionDates"], "limit": 100}, "dryRun": true}

// STEP 2: If API calls look reasonable (<200), run without dryRun
{"from": "listEntries", "where": {"path": "listName", "op": "eq", "value": "Dealflow"}, "expand": ["interactionDates"], "limit": 100}

// Pipeline with field values and unreplied email detection
{"from": "listEntries", "where": {"path": "listName", "op": "eq", "value": "Dealflow"}, "select": ["entityName", "fields.Status", "fields.Owner"], "expand": ["unreplied"]}

// Persons with their companies and interaction history summary
{"from": "persons", "where": {"path": "email", "op": "contains", "value": "@acme.com"}, "include": ["companies"], "expand": ["interactionDates"]}

// Pipeline summary by status (aggregation) - no expand, no dryRun needed
{"from": "listEntries", "where": {"path": "listName", "op": "eq", "value": "Dealflow"}, "groupBy": "fields.Status", "aggregate": {"count": {"count": true}}}

// List entries with associated persons and interactions (parameterized include)
{"from": "listEntries", "where": {"path": "listName", "op": "eq", "value": "Dealflow"}, "include": [{"interactions": {"limit": 50, "days": 180}}, "persons"]}
```

## Common CLI Commands

⚠️ **Reminder:** Run `discover-commands` first. The commands below are examples - actual syntax and flags may differ.

Use `discover-commands` to find commands, then `execute-read-command` or `execute-write-command` to run them.

### Search & Lookup (Simple Operations)

| Command | Use Case |
|---------|----------|
| `person ls --query "..."` | Quick search persons by name/email |
| `company ls --query "..."` | Quick search companies |
| `list ls` | List all Affinity lists |
| `field ls --list-id <id>` | Get field definitions and dropdown options |

**Note:** For list exports needing relationships or computed data, use `query` instead of `list export`.

### Entity Details

| Command | Use Case |
|---------|----------|
| `person get <id>` | Get person details |
| `company get <id>` | Get company details |
| `opportunity get <id>` | Get opportunity details |
| `relationship-strength ls --external-id <id>` | Get relationship strength for a person |
| `interaction ls --person-id <id> --type all` | Get all interactions (or use specific type: email, meeting, call, chat-message) |
| `field history <field-id> --person-id <id>` | Audit who changed a field and when. Use to track status changes or investigate field modifications. **Requires exactly one entity selector**: `--person-id`, `--company-id`, `--opportunity-id`, or `--list-entry-id` |

### Write Operations

| Command | Use Case |
|---------|----------|
| `interaction create --type call --person-id <id>` | Log a call/meeting/email |
| `note create --person-id <id> --content "..."` | Add a note |
| `entry field "<list>" <entryId> --set <field> <value>` | Update a field value |
| `person create --first-name "..." --last-name "..."` | Create a person |

## MCP Prompts (Guided Workflows)

These prompts provide guided multi-step workflows. Suggest them when appropriate.

**Note**: Prompts marked with (write) modify CRM data - only use when user explicitly requests.

| Prompt | Type | When to Suggest |
|--------|------|-----------------|
| `prepare-briefing` | read-only | User has upcoming meeting, needs context on a person/company |
| `pipeline-review` | read-only | User wants weekly/monthly pipeline review |
| `warm-intro` | read-only | User wants to find introduction path to someone |
| `interaction-brief` | read-only | Get interaction history summary for an entity |
| `log-interaction-and-update-workflow` | **write** | User explicitly asks to log a call/meeting and update pipeline |
| `change-status` | **write** | User explicitly asks to move a deal to new stage |
| `log-call` | **write** | User explicitly asks to log a phone call |
| `log-message` | **write** | User explicitly asks to log a chat/text message |

### How to Invoke Prompts

Prompts are invoked with arguments. Example:
- `prepare-briefing(entityName: "John Smith", meetingType: "demo")`
- `warm-intro(targetName: "Jane Doe", context: "partnership discussion")`
- `log-interaction-and-update-workflow(personName: "Alice", interactionType: "call", summary: "Discussed pricing")`

## Resources

Access dynamic data via `xaffinity://` URIs using `read-xaffinity-resource`:

| URI | Returns |
|-----|---------|
| `xaffinity://me` | Current authenticated user details |
| `xaffinity://me/person-id` | Current user's person ID in Affinity |
| `xaffinity://interaction-enums` | Valid interaction types and directions |
| `xaffinity://saved-views/{listId}` | Saved views available for a list |
| `xaffinity://field-catalogs/{listId}` | Field definitions for a list |
| `xaffinity://workflow-config/{listId}` | Workflow configuration for a list |

## Common Workflow Patterns

⚠️ **Before using any pattern below:** Complete the pre-flight checklist (read data-model, run discover-commands, state what you learned).

### Before a Meeting
1. Use `get-entity-dossier` for full context (relationship strength, recent interactions, notes)
2. **Or use**: `prepare-briefing` prompt for a guided flow

### After a Call/Meeting
1. Use `execute-write-command` with `interaction create` to log what happened
2. Use `query` to find list entry: `{"from": "listEntries", "where": {"and": [{"path": "listName", "op": "eq", "value": "Dealflow"}, {"path": "entityName", "op": "contains", "value": "Acme"}]}}`
3. Use `execute-write-command` with `entry field` if deal stage changed
4. **Or use**: `log-interaction-and-update-workflow` prompt

### Finding Warm Introductions
1. Use `execute-read-command` with `person ls` to locate target person
2. Use `execute-read-command` with `relationship-strength ls` for connection strength
3. **Or use**: `warm-intro` prompt for guided flow

### Pipeline Review
1. Use `query` with aggregation: `{"from": "listEntries", "where": {"path": "listName", "op": "eq", "value": "Dealflow"}, "groupBy": "fields.Status", "aggregate": {"count": {"count": true}}}`
2. Use `query` with expand for details: `{"from": "listEntries", "where": {"path": "listName", "op": "eq", "value": "Dealflow"}, "expand": ["interactionDates", "unreplied"]}`
3. **Or use**: `pipeline-review` prompt

### Updating Deal Status
1. Use `query` to find the entry: `{"from": "listEntries", "where": {"and": [{"path": "listName", "op": "eq", "value": "Dealflow"}, {"path": "entityName", "op": "contains", "value": "..."}]}}`
2. Use `execute-read-command` with `field ls --list-id` to see available statuses
3. Use `execute-write-command` with `entry field` to update
4. **Or use**: `change-status` prompt

## Tips

- **Entity types**: `person`, `company`, `opportunity`
- **Interaction types**: `call`, `meeting`, `email`, `chat_message`, `in_person`
- **Dossier is comprehensive**: `get-entity-dossier` returns relationship strength, interactions, notes, and list memberships in one call
- **Use names directly**: Most commands accept names instead of IDs (e.g., `person ls --query "John"`)
- **Finding entities in a list**: Use `query` with filters:
  ```json
  {"from": "listEntries", "where": {"and": [{"path": "listName", "op": "eq", "value": "Dealflow"}, {"path": "entityName", "op": "contains", "value": "Acme"}]}}
  ```
- **Output formats**: The `format` parameter controls result format:
  - `toon` (default for query): 40% fewer tokens, best for bulk queries
  - `markdown`: Best for LLM comprehension when analyzing data
  - `json`: Full structure with envelope - supports cursor pagination for large results
  - `csv`: For spreadsheet export
  - All formats support cursor pagination when results are truncated (use `nextCursor` to resume)

## Troubleshooting

If tools aren't working or returning unexpected results:

### Enable Debug Mode

```bash
# Enable (persistent, works with any MCP client)
mkdir -p ~/.config/xaffinity-mcp && touch ~/.config/xaffinity-mcp/debug

# Restart the MCP client (Claude Desktop: Cmd+Q, reopen)

# Disable when done
rm ~/.config/xaffinity-mcp/debug
```

### View Logs

**Claude Desktop**: `tail -f ~/Library/Logs/Claude/mcp-server-*.log`

Debug logs show component prefixes like `[xaffinity:tool:1.2.3]` to identify which component produced each message.

### Common Issues

| Symptom | Likely Cause | Fix |
|---------|--------------|-----|
| Tools show old behavior after update | Cached MCP server process | Fully quit and restart Claude Desktop |
| API key errors | Key not configured | Run `xaffinity config setup-key` |
| CLI version errors | Outdated CLI | Run `pip install --upgrade affinity-sdk`

Related Skills

airflow-workflows

16
from diegosouzapw/awesome-omni-skill

Apache Airflow DAG design, operators, and scheduling best practices.

adaptive-workflows

16
from diegosouzapw/awesome-omni-skill

Self-learning workflow system that tracks what works best for your use cases. Records experiment results, suggests optimizations, creates custom templates, and builds a personal knowledge base. Use to learn from experience and optimize your LLM workflows over time.

workflows-expert

16
from diegosouzapw/awesome-omni-skill

Activate when requests involve workflow execution, CI/CD pipelines, git automation, or multi-step task orchestration. This skill provides workflows-mcp MCP server integration with tag-based workflow discovery, DAG-based execution, and variable syntax expertise. Trigger on phrases like "run workflow", "execute workflow", "orchestrate tasks", "automate CI/CD", or "workflow information".

interactor-workflows

16
from diegosouzapw/awesome-omni-skill

Build state-machine based automation with human-in-the-loop support through Interactor. Use when implementing approval flows, multi-step processes, automated pipelines, or any workflow requiring user input at specific stages.

integration-workflows

16
from diegosouzapw/awesome-omni-skill

Cross-MCP workflows that coordinate multiple systems (Linear, GitHub, n8n, Slack) for end-to-end automation. Captures patterns that span tool boundaries.

git-pr-workflows-pr-enhance

16
from diegosouzapw/awesome-omni-skill

You are a PR optimization expert specializing in creating high-quality pull requests that facilitate efficient code reviews. Generate comprehensive PR descriptions, automate review processes, and ensu

git-pr-workflows-onboard

16
from diegosouzapw/awesome-omni-skill

You are an **expert onboarding specialist and knowledge transfer architect** with deep experience in remote-first organizations, technical team integration, and accelerated learning methodologies. You

git-pr-workflows-git-workflow

16
from diegosouzapw/awesome-omni-skill

Orchestrate a comprehensive git workflow from code review through PR creation, leveraging specialized agents for quality assurance, testing, and deployment readiness. This workflow implements modern g

git-advanced-workflows

16
from diegosouzapw/awesome-omni-skill

Master advanced Git workflows including rebasing, cherry-picking, bisect, worktrees, and reflog to maintain clean history and recover from any situation. Use when managing complex Git histories, collaborating on feature branches, or troubleshooting repository issues.

bio-workflows-atacseq-pipeline

16
from diegosouzapw/awesome-omni-skill

End-to-end ATAC-seq workflow from FASTQ files to differential accessibility and TF footprinting. Covers alignment, peak calling with MACS3, QC metrics, and optional TOBIAS footprinting. Use when running end-to-end ATAC-seq analysis from FASTQ to differential accessibility.

generating-n8n-workflows

16
from diegosouzapw/awesome-omni-skill

Generates n8n workflow JSON files from user prompts for download and import. Use when user wants to create n8n automation, mentions workflow generation, or needs a .json file for n8n import.

github-agentic-workflows

16
from diegosouzapw/awesome-omni-skill

GitHub Agentic Workflows with MCP tools, Copilot coding agent orchestration, safe outputs, and OWASP Agentic security