# Attio MCP Server (npm · attio-mcp)

AI-powered Attio CRM access. Manage contacts, companies, deals, tasks, notes and workflows.

- Trust score: 76/100 (medium)
- Change this week: +24
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- npm · `attio-mcp`: 76/100 (this document), [markdown](https://verifymcp.io/servers/kesslerio-attio-mcp-server/attio-mcp.md), [page](https://verifymcp.io/servers/kesslerio-attio-mcp-server/attio-mcp)

## Channel facts

- Registry: `npm`
- Package: `attio-mcp`
- Version: `1.6.1`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-03.

- **Supply Chain Security**: 77/100
  - No malware found by supply-chain analysis.
  - CVE check failed: a known medium-severity CVE affects @hono/node-server 1.19.17, reached via @modelcontextprotocol/sdk > @hono/node-server. A fixed version is available.
  - Runs a script at install time (postinstall) that we could not recognise. It may be perfectly ordinary, but we do not read the published tarball, so we cannot say what it does.
  - Only part of the dependency tree could be resolved (165 of 166), so this covers what we could see, not the whole tree.
- **Provenance & Transparency**: 97/100
  - Source repository is publicly reachable at the declared URL.
  - Cryptographically verified build provenance (signed, bound to kesslerio/attio-mcp-server).
  - Clear OSI-approved license (Apache-2.0).
  - Actively maintained (last published 80 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 73/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 8515 tokens (~198/item across 43 items; 43 tools + 0 resources), over budget; trim descriptions and params.
  - Tools include usage examples.
- **Stability & Change Management**: 23/100
  - Stability observed for 7 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add kesslerio-attio-mcp-server -- npx -y attio-mcp
```

### Codex

```bash
codex mcp add kesslerio-attio-mcp-server -- npx -y attio-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "kesslerio-attio-mcp-server": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "attio-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add kesslerio-attio-mcp-server --command npx --arg -y --arg attio-mcp
```

### Hermes

```yaml
mcp_servers:
  kesslerio-attio-mcp-server:
    command: "npx"
    args: ["-y", "attio-mcp"]
```

### Other

```json
{
  "mcpServers": {
    "kesslerio-attio-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "attio-mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-03 (score 76, +1)

No change was recorded against any check on this day. Stability & Change Management went from 20 to 23. That category is still filling its 30-day observation window: 6 days of observed history at the previous scan, 7 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-08-02 (score 75, +35)

- [security regression] GHSA-frvp-7c67-39w9 affects this package: medium
- [security regression] Known CVEs: unverified → fail
- [security improvement] Install scripts: unverified → partial
- [security improvement] Provenance: unverified → pass
- [security] The scripts that run when this package is installed changed: postinstall
- [security] The attested source repository moved: kesslerio/attio-mcp-server
- [functional regression] Schema quality: 100 → unverified
- [functional regression] Security disclosure: fail → unverified
- [functional regression] Tool coverage: 100 → unverified
- [functional improvement] License: unverified → pass
- [functional improvement] Dependency health: unverified → partial
- [functional improvement] Stability: unverified → 0.20
- [functional improvement] Maintenance: unverified → pass
- [functional improvement] MCP protocol: unverified → pass
- [functional improvement] Schema quality: unverified → good
- [functional] Licence: Apache-2.0

### 2026-08-01 (score 40, +15)

- [security improvement] Malware scan: unverified → pass

### 2026-07-31 (score 25, −27)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-27 (score 52)

First indexed and scored.

## MCP tools (43)

### `aaa-health-check` (~61 tokens)

Run a lightweight health probe that echoes deployment metadata. Never query Attio APIs, mutate data, or require credentials. Accepts optional echo text; returns JSON payload as text for MCP clients. If unavailable, review Smithery sandbox logs or restart the server process.

### `smithery_debug_config` (~69 tokens)

Retrieve non-sensitive diagnostic information about Smithery runtime configuration propagation. Never expose credentials or auth state, write data, or modify configuration. Returns runtime, workspace, and context-storage diagnostics only. Read-only operation. Use this tool to compare runtime mode, workspace configuration, and context storage state across deployments.

### `search_records` (~1079 tokens)

Search across companies, people, deals, tasks, and records. Never create or modify records. Returns max 100 results (default: 10). use discover_record_attributes to find searchable fields.

Input parameters:

- `created_after` (string): Filter records created after this date (ISO 8601)
- `created_before` (string): Filter records created before this date (ISO 8601)
- `date_field` (string): Which date field to filter on. Attio supports created_at and last_interaction for people and companies. updated_at/modifed-style filtering is not supported live on those objects.
- `date_from` (string): Start date for filtering (ISO 8601 format)
- `date_to` (string): End date for filtering (ISO 8601 format)
- `fields` (array): Fields to search (content)
- `filters` (object): Advanced filter conditions with nested array structure. Required format: {   "filters": [     {       "attribute": {"slug": "field_name"},        "condition": "operator",        "value": "search_val…
- `limit` (number): Maximum number of results to return
- `match_type` (string): String matching
- `offset` (number): Number of results to skip for pagination
- `query` (string): Search query string
- `resource_type` (string, required): Type of resource to operate on. Standard types: companies, people, deals, tasks, lists, records, notes. Custom objects (e.g., "funds", "investment_opportunities") are also supported after running `at…
- `search_type` (string): Type of search
- `sort` (string): Sort order
- `timeframe` (string): Relative timeframe filter
- `updated_after` (string): Filter records updated after this date (ISO 8601)
- `updated_before` (string): Filter records updated before this date (ISO 8601)

### `get_record_details` (~136 tokens)

Fetch a single record with enriched attribute formatting. Never search or filter result sets; use records.search* tools instead. Requires resource_type and record_id; optional fields filter output. Validate record IDs with records.search before retrying.

Input parameters:

- `fields` (array): Fields to include
- `record_id` (string, required): Record ID to retrieve
- `resource_type` (string, required): Type of resource to operate on. Standard types: companies, people, deals, tasks, lists, records, notes. Custom objects (e.g., "funds", "investment_opportunities") are also supported after running `at…

### `create_company` (~106 tokens)

Create one company in Attio without choosing resource_type. Never update existing companies or create deals, people, or tasks. May require explicit user approval from the host. Requires record_data with company attribute API slugs such as name, domains, or website. If fields are rejected, call discover_record_attributes with resource_type companies.

Input parameters:

- `record_data` (object, required): Company fields to create. Use Attio attribute API slugs as keys.
- `return_details` (boolean): Return full details

### `update_company` (~115 tokens)

Update one company in Attio without choosing resource_type. Never create records, delete records, or update deals. May require explicit user approval from the host. Requires record_id and record_data with company attribute API slugs. Call get_record_details or search_records for companies first to confirm the target company ID.

Input parameters:

- `record_data` (object, required): Company fields to update. Use Attio attribute API slugs as keys.
- `record_id` (string, required): Company record ID to update
- `return_details` (boolean): Return full details

### `create_deal` (~120 tokens)

Create one deal in Attio without choosing resource_type. Never update existing deals or create companies, people, or tasks. May require explicit user approval from the host. Requires record_data with deal attribute API slugs such as name, stage, value, owner, or associated company/person references. If stage or owner values are rejected, call discover_record_attributes or get_record_attribute_options for deals.

Input parameters:

- `record_data` (object, required): Deal fields to create. Use Attio attribute API slugs as keys.
- `return_details` (boolean): Return full details

### `update_deal` (~115 tokens)

Update one deal in Attio without choosing resource_type. Never create records, delete records, or update companies. May require explicit user approval from the host. Requires record_id and record_data with deal attribute API slugs. Call search_records for deals first to confirm the target deal ID and current stage.

Input parameters:

- `record_data` (object, required): Deal fields to update. Use Attio attribute API slugs as keys.
- `record_id` (string, required): Deal record ID to update
- `return_details` (boolean): Return full details

### `create_record` (~196 tokens)

Create new Attio records across supported resource types when a scoped tool is not available. Prefer create_company or create_deal for common company/deal writes. Never update existing records, attach files, or bypass required fields. May require explicit user approval from the host. Requires resource_type plus record_data that matches discover_record_attributes output. If validation fails, call records_discover_attributes to confirm required fields and enums. If a select/status value is rejected, call records_get_attribute_options for that attribute to list valid options before retrying.

Input parameters:

- `record_data` (object, required): Data to create
- `resource_type` (string, required): Type of resource to operate on. Standard types: companies, people, deals, tasks, lists, records, notes. Custom objects (e.g., "funds", "investment_opportunities") are also supported after running `at…
- `return_details` (boolean): Return full details

### `update_record` (~207 tokens)

Update existing Attio record fields across supported resource types when a scoped tool is not available. Prefer update_company or update_deal for common company/deal writes. Never create new records, delete data, or manage list memberships. May require explicit user approval from the host. Requires resource_type, record_id, and record_data; supports partial updates with schema validation. Call records_get_details first to inspect the latest values before editing. If a select/status value is rejected, call records_get_attribute_options for that attribute to list valid options.

Input parameters:

- `record_data` (object, required): Updated data
- `record_id` (string, required): Record ID to update
- `resource_type` (string, required): Type of resource to operate on. Standard types: companies, people, deals, tasks, lists, records, notes. Custom objects (e.g., "funds", "investment_opportunities") are also supported after running `at…
- `return_details` (boolean): Return full details

### `delete_record` (~146 tokens)

Delete an Attio record from its object (company, person, deal, task). Never cascade delete related data or clean up list memberships automatically. May require explicit user approval from the host. Requires record_id and resource_type; operation is irreversible once confirmed. If uncertain, fetch with records_get_details to confirm the target before deletion.

Input parameters:

- `record_id` (string, required): Record ID to delete
- `resource_type` (string, required): Type of resource to operate on. Standard types: companies, people, deals, tasks, lists, records, notes. Custom objects (e.g., "funds", "investment_opportunities") are also supported after running `at…

### `get_record_attributes` (~142 tokens)

Retrieve attribute metadata for a given resource type. Never modify schema definitions or record data. Requires resource_type; optional categories narrows groups. Use records.discover_attributes for grouped schema discovery.

Input parameters:

- `categories` (array): Attribute categories
- `fields` (array): Specific attribute field names
- `record_id` (string): Record ID to get attributes for (optional)
- `resource_type` (string, required): Type of resource to operate on. Standard types: companies, people, deals, tasks, lists, records, notes. Custom objects (e.g., "funds", "investment_opportunities") are also supported after running `at…

### `discover_record_attributes` (~125 tokens)

Discover available attributes (standard/custom) for a resource. Never alter schema or create fields. Requires resource_type; optional categories selects subsets. For select/status attributes, use get_record_attribute_options to fetch valid values before creating or updating records.

Input parameters:

- `categories` (array): Attribute categories
- `resource_type` (string, required): Type of resource to operate on. Standard types: companies, people, deals, tasks, lists, records, notes. Custom objects (e.g., "funds", "investment_opportunities") are also supported after running `at…

### `get_record_attribute_options` (~177 tokens)

Get valid options for select, multi-select, and status attributes to avoid "Cannot find select option" errors. Never return options for text, number, or other non-option types. Requires resource_type and attribute slug/ID. Use discover_record_attributes to find option-based attributes first. Use retrieved option titles when calling create-record or update-record.

Input parameters:

- `attribute` (string, required): The attribute slug or ID (e.g., "channel", "stage", "categories")
- `resource_type` (string, required): Type of resource to operate on. Standard types: companies, people, deals, tasks, lists, records, notes. Custom objects (e.g., "funds", "investment_opportunities") are also supported after running `at…
- `show_archived` (boolean): Include archived options in the response

### `get_record_info` (~86 tokens)

Retrieve enriched info subsets (contact, business, social) for a record. Never search lists of records or mutate data. Requires resource_type, record_id, and info_type (contact|business|social). Use records.get_details if you need the full record payload.

Input parameters:

- `record_id` (string, required): Unique identifier of the record
- `resource_type` (string, required): Type of resource

### `create_note` (~219 tokens)

Create note for companies, people, or deals with full markdown support. Never update or delete notes; creates only. May require explicit user approval from the host. Requires resource_type, record_id, title, content. Set format="markdown" for rich formatting: headings (# ## ###), lists (- or 1.), nested bullets (2-space indent), bold (**text**), code blocks. Use \n for line breaks. If record not found, use records_search first.

Input parameters:

- `content` (string, required): Note content. Use \n for line breaks. With format="markdown": supports # headings, - bullets, 1. numbered lists, **bold**, `code`, nested lists (2-space indent).
- `format` (string): Content format. Use "markdown" for rich text: headings, lists, bold, code blocks. Default: plaintext.
- `record_id` (string, required): ID of the record to attach the note to
- `resource_type` (string, required): Target resource type
- `title` (string, required): Title of the note

### `list_notes` (~167 tokens)

Retrieve notes for a record with timestamps. Never create or modify notes; read-only. Requires resource_type, record_id; sorted by creation date. If empty, verify record has notes with records_get_details.

Input parameters:

- `limit` (number): Maximum number of results to return
- `offset` (number): Number of results to skip for pagination
- `parent_record_id` (string): Alias for record_id (backward compatibility)
- `record_id` (string): Record ID to list notes for
- `resource_type` (string, required): Type of resource to operate on. Standard types: companies, people, deals, tasks, lists, records, notes. Custom objects (e.g., "funds", "investment_opportunities") are also supported after running `at…

### `get_record_interactions` (~131 tokens)

Fetch interaction metadata (first/last email, calendar, interaction timestamps and owners) for a person or company record. Never retrieve full email content or activity feeds; Attio only exposes interaction timestamps and owner actors. Requires resource_type (people or companies) and record_id. Returns system-generated interaction attributes. If no interactions found, verify the record exists with get_record_details. For activity content, use search_records_by_content with content_type=activity.

Input parameters:

- `record_id` (string, required): Record ID to retrieve interactions for
- `resource_type` (string, required): Resource type (only people and companies have interaction metadata)

### `search_records_advanced` (~482 tokens)

Search companies, people, deals, or tasks with complex nested filters (e.g., find deals by owner+stage, companies by industry+location). Never mutate records; use records.update or records.delete. Supports filter groups, scoring, pagination, and up to 100 items. Requires resource_type parameter. If filters fail, fetch valid attributes via records.discover_attributes.

Input parameters:

- `filters` (object): Complex filter conditions with nested array structure. Required format: {   "filters": [     {       "attribute": {"slug": "field_name"},        "condition": "operator",        "value": "search_valu…
- `limit` (number): Maximum number of results to return
- `offset` (number): Number of results to skip for pagination
- `query` (string): Search query string
- `resource_type` (string, required): Type of resource to operate on. Standard types: companies, people, deals, tasks, lists, records, notes. Custom objects (e.g., "funds", "investment_opportunities") are also supported after running `at…
- `sort_by` (string): Field to sort results by
- `sort_order` (string): Sort order

### `search_records_by_relationship` (~130 tokens)

Search records using relationship anchors (list, company, people). Never modify memberships; use list tools for writes. Requires resource_type and related resource identifier. Use records.search to resolve IDs before calling.

Input parameters:

- `limit` (number): Maximum number of results to return
- `listId` (string): (Optional) List ID (must be a valid UUID if provided)
- `offset` (number): Number of results to skip for pagination
- `relationship_type` (string, required): Relationship type
- `source_id` (string, required): Source record ID
- `target_resource_type` (string): Target resource type

### `search_records_by_content` (~163 tokens)

Search record content (notes, activity, communications). Never modify note content or attachments. Requires resource_type and content_query; optional fields array. Narrow scope with fields or switch to records.search_advanced.

Input parameters:

- `content_type` (string, required): Type of content to search
- `limit` (number): Maximum number of results to return
- `offset` (number): Number of results to skip for pagination
- `resource_type` (string, required): Type of resource to operate on. Standard types: companies, people, deals, tasks, lists, records, notes. Custom objects (e.g., "funds", "investment_opportunities") are also supported after running `at…
- `search_query` (string, required): Query to search within content

### `search_records_by_timeframe` (~224 tokens)

Filter records by creation, update, or interaction timeframes. Never modify lifecycle state or scheduling follow-ups. Requires resource_type; provide timeframe or explicit date boundaries. Call records.search if timeframe filters are too restrictive.

Input parameters:

- `date_field` (string): Optional explicit date field override. last_interaction is supported for people and companies; updated_at and modified_at remain accepted aliases but are not supported live on those objects.
- `end_date` (string): End date (ISO 8601 format)
- `limit` (number): Maximum number of results to return
- `offset` (number): Number of results to skip for pagination
- `resource_type` (string, required): Type of resource to operate on. Standard types: companies, people, deals, tasks, lists, records, notes. Custom objects (e.g., "funds", "investment_opportunities") are also supported after running `at…
- `start_date` (string): Start date (ISO 8601 format)
- `timeframe_type` (string): Timeframe filter type

### `batch_records` (~229 tokens)

Execute batched record operations (create/update/delete/get/search). Never ignore approval guardrails; hosts may require confirmation. May require explicit user approval from the host. Use scoped single-record tools for one company or deal write. operation_type must be specified for legacy payloads; operations arrays must use explicit create/update/delete entries. Run records.search first to stage IDs or payloads for batching.

Input parameters:

- `limit` (number): Maximum number of results to return
- `offset` (number): Number of results to skip for pagination
- `operation_type` (string): Batch operation type (legacy format)
- `operations` (array): Array of operations to perform
- `record_ids` (array): Record IDs for delete/get (legacy format)
- `records` (array): Record data for create/update (legacy format)
- `resource_type` (string, required): Type of resource to operate on. Standard types: companies, people, deals, tasks, lists, records, notes. Custom objects (e.g., "funds", "investment_opportunities") are also supported after running `at…

### `batch_search_records` (~127 tokens)

Execute multiple searches in parallel and return grouped results. Never mutate or import data; use records.batch for write operations. Provide queries array (1–10 items recommended) and resource_type. If queries fail, retry individually using records.search.

Input parameters:

- `limit` (number): Maximum number of results per query (default: 20)
- `offset` (number): Number of results to skip per query (default: 0)
- `queries` (array, required): Array of search query strings
- `resource_type` (string, required): Resource type to search (companies, people, records, tasks, deals)

### `search` (~129 tokens)

Run lightweight compatibility search across companies, people, lists, and tasks for ChatGPT MCP. Never support complex filters, batch queries, or return rich record payloads (use records_search* tools). Requires query string (min 1 char); optional type filter; limit up to 25 results per call. When you need pagination or attribute filtering, switch to records_search or records_search_advanced.

Input parameters:

- `limit` (integer): Maximum number of results to return (default 10).
- `query` (string, required): Search query string (required).
- `type` (string): Optional resource filter (defaults to all).

### `fetch` (~90 tokens)

Return the canonical Attio record payload for a search connector reference. Never perform write operations or resolve IDs not emitted by the search tool. Accepts identifier generated by search (<resource>:<uuid>) and returns JSON serialized as text. If fetch fails, rerun search to refresh the identifier or verify the record still exists.

Input parameters:

- `id` (string, required): Identifier emitted by the search tool (<resource>:<id>).

### `get-lists` (~53 tokens)

Retrieve all CRM lists (sales pipelines, lead stages, customer segments). Never create or modify lists, only reads existing lists. Returns all lists visible to the authenticated workspace. Use get-list-details to inspect individual list schemas.

### `get-record-list-memberships` (~145 tokens)

Find all lists containing a specific company or person record. Never modify list memberships or retrieve list entries. Requires recordId; processes 5 lists in parallel by default (max 20). If record not found, verify recordId with records_search first.

Input parameters:

- `batchSize` (number): Number of lists to process in parallel (1-20, default: 5)
- `includeEntryValues` (boolean): Whether to include entry values in the response (e.g., stage, status)
- `objectType` (string): Type of record (e.g., "companies", "people")
- `recordId` (string, required): ID of the record to find in lists

### `get-list-details` (~77 tokens)

Retrieve schema and configuration for a specific list (stages, fields, attributes). Never modify list structure or retrieve list entries. Requires valid list UUID or slug; accepts both formats. Use get-lists to discover available list IDs and slugs first.

Input parameters:

- `listId` (string, required): ID or slug of the list to get details for

### `get-list-entries` (~116 tokens)

Retrieve all records in a list with pagination (companies, people in pipelines). Never filter entries or modify list memberships. Requires list UUID (not slug); default limit 20, max per page varies by API. Use filter-list-entries for attribute-based filtering instead.

Input parameters:

- `limit` (number): Maximum number of entries to fetch (default: 20)
- `listId` (string, required): UUID of the list to get entries for
- `offset` (number): Number of entries to skip for pagination (default: 0)

### `filter-list-entries` (~816 tokens)

Filter list entries with flexible parameter modes. Auto-detects mode based on parameters provided.

\**Mode 1 - Simple Filtering (Single Attribute):**
Filter entries by a single attribute condition.
Required parameters: listId, attributeSlug, condition, value

Example:
{
  "listId": "550e8400-e29b-41d4-a716-446655440000",
  "attributeSlug": "status",
  "condition": "equals",
  "value": "active"
}

\**Mode 2 - Advanced Filtering (Multi-Condition):**
Filter entries with multiple conditions using AND/OR logic.
Required parameters: listId, filters (object with filters array and matchAny flag)

Example:
{
  "listId": "550e8400-e29b-41d4-a716-446655440000",
  "filters": {
    "filters": [
      {"attribute": {"slug": "status"}, "condition": "equals", "value": "active"},
      {"attribute": {"slug": "priority"}, "condition": "greater_than", "value": 5}
    ],
    "matchAny": false
  }
}

\**Mode 3 - Parent Attribute Filtering:**
Filter entries by parent record attributes (e.g., company industry, person role).
Required parameters: listId, parentObjectType, parentAttributeSlug, condition, value

Example:
{
  "listId": "550e8400-e29b-41d4-a716-446655440000",
  "parentObjectType": "companies",
  "parentAttributeSlug": "categories",
  "condition": "contains",
  "value": "Technology"
}

\**Mode 4 - Parent UUID Filtering:**
Filter entries by exact parent record UUID (convenience mode, fastest).
Required parameters: listId, parentRecordId

Example:
{
  "listId": "550e8400-e29b-41d4-a716-446655440000",
  "parentRecordId": "660e8400-e29b-41d4-a716-446655440001"
}

\**Mode Detection:**
The tool automatically detects which mode to use based on the parameters you provide.
You must provide parameters for exactly ONE mode per call.

\**Pagination:**
All modes support optional 'limit' and 'offset' parameters for pagination.

\**Migration Guide:**
\- Replaces: advanced-filter-list-entries → Use Mode 2 (filters parameter)
\- Replaces: filter-list-entries-by-parent → Use Mode 3 (parentObjectType + p…

Input parameters:

- `attributeSlug` (string): Mode 1: Slug of the attribute to filter by (e.g., 'stage', 'status')
- `condition` (string): Mode 1 & 3: Filter condition (e.g., 'equals', 'contains', 'greater_than')
- `filters` (object): Mode 2: Advanced filter configuration with multiple conditions
- `limit` (number): Maximum number of entries to fetch (default: 20, applies to all modes)
- `listId` (string, required): UUID of the list to filter entries from (required for all modes)
- `offset` (number): Number of entries to skip for pagination (default: 0, applies to all modes)
- `parentAttributeSlug` (string): Mode 3: Attribute of the parent record to filter by (e.g., "name", "email_addresses", "categories")
- `parentObjectType` (string): Mode 3: Type of the parent record (e.g., "companies", "people")
- `parentRecordId` (string): Mode 4: UUID of the parent record to filter by (fastest mode for exact record filtering)
- `value`: Mode 1 & 3: Value to filter by (type depends on the attribute)

### `advanced-filter-list-entries` (~189 tokens)

[DEPRECATED] This tool has been consolidated into 'filter-list-entries'.

Please use 'filter-list-entries' with Mode 2 (Advanced) parameters instead:
\- Pass a 'filters' object with 'filters' array and 'matchAny' flag
\- All functionality remains identical

This tool will be removed in version 2.0.0.

\---

Filter entries with multi-condition queries (AND/OR logic). Never modify entries; read-only. Requires listId, filters array; matchAny for OR logic. Use filter-list-entries for single conditions.

Input parameters:

- `filters` (object, required): Advanced filter configuration
- `limit` (number): Maximum number of entries to fetch (default: 20)
- `listId` (string, required): ID of the list to filter entries from
- `offset` (number): Number of entries to skip for pagination (default: 0)

### `add-record-to-list` (~206 tokens)

[DEPRECATED] This tool has been consolidated into 'manage-list-entry'.

Please use 'manage-list-entry' with Mode 1 (Add) parameters instead:
\- Pass 'recordId', 'objectType', and optionally 'initialValues'
\- All functionality remains identical

This tool will be removed in version 2.0.0.

Add company or person to list with optional initial values. Never create records; record must exist first. May require explicit user approval from the host. Requires list UUID, record UUID, object type. If not found, create record first with create-record.

Input parameters:

- `initialValues` (object): Initial values for the list entry (e.g., {"stage": "Prospect"})
- `listId` (string, required): UUID of the list to add the record to
- `objectType` (string, required): Type of record (e.g., "companies", "people")
- `recordId` (string, required): UUID of the record to add to the list

### `remove-record-from-list` (~166 tokens)

[DEPRECATED] This tool has been consolidated into 'manage-list-entry'.

Please use 'manage-list-entry' with Mode 2 (Remove) parameters instead:
\- Pass 'entryId' only (do not include 'attributes' or 'recordId')
\- All functionality remains identical

This tool will be removed in version 2.0.0.

Remove company or person from list (membership only). Never delete underlying record; membership only. May require explicit user approval from the host. Requires list UUID, entry UUID (not record UUID). Use get-list-entries to find entry UUID.

Input parameters:

- `entryId` (string, required): UUID of the list entry to remove (not the record ID)
- `listId` (string, required): UUID of the list to remove the entry from

### `update-list-entry` (~169 tokens)

[DEPRECATED] This tool has been consolidated into 'manage-list-entry'.

Please use 'manage-list-entry' with Mode 3 (Update) parameters instead:
\- Pass 'entryId' and 'attributes' parameters
\- All functionality remains identical

This tool will be removed in version 2.0.0.

Update list entry attributes (stage, status, custom fields). Never update record attributes; use update-record for that. May require explicit user approval from the host. Requires list UUID, entry UUID, attributes object. Use get-list-details for valid attributes and values.

Input parameters:

- `attributes` (object, required): Attributes to update on the list entry
- `entryId` (string, required): UUID of the list entry to update
- `listId` (string, required): UUID of the list containing the entry

### `manage-list-entry` (~526 tokens)

Manage list entries with flexible action modes. Auto-detects action based on parameters provided.

\**Mode 1 - Add Entry (Add record to list):**
Add a company or person record to a list with optional initial values.
Required parameters: listId, recordId, objectType
Optional parameters: initialValues

Example:
{
  "listId": "550e8400-e29b-41d4-a716-446655440000",
  "recordId": "660e8400-e29b-41d4-a716-446655440001",
  "objectType": "companies",
  "initialValues": {"stage": "Prospect"}
}

\**Mode 2 - Remove Entry:**
Remove an entry from a list.
Required parameters: listId, entryId

Example:
{
  "listId": "550e8400-e29b-41d4-a716-446655440000",
  "entryId": "770e8400-e29b-41d4-a716-446655440002"
}

\**Mode 3 - Update Entry:**
Update attributes on an existing list entry.
Required parameters: listId, entryId, attributes

Example:
{
  "listId": "550e8400-e29b-41d4-a716-446655440000",
  "entryId": "770e8400-e29b-41d4-a716-446655440002",
  "attributes": {"stage": "Qualified"}
}

\**Mode Detection:**
The tool automatically detects which action to perform based on the parameters you provide.
You must provide parameters for exactly ONE mode per call.

\**Migration Guide:**
\- Replaces: add-record-to-list → Use Mode 1 (recordId + objectType)
\- Replaces: remove-record-from-list → Use Mode 2 (entryId only)
\- Replaces: update-list-entry → Use Mode 3 (entryId + attributes)

Input parameters:

- `attributes` (object): Mode 3: Attributes to update on the list entry
- `entryId` (string): Mode 2 & 3: UUID of the list entry to remove or update
- `initialValues` (object): Mode 1: Initial attribute values for the list entry
- `listId` (string, required): UUID of the list (required for all modes)
- `objectType` (string): Mode 1: Type of record to add
- `recordId` (string): Mode 1: UUID of the record to add to the list

### `filter-list-entries-by-parent` (~275 tokens)

[DEPRECATED] This tool has been consolidated into 'filter-list-entries'.

Please use 'filter-list-entries' with Mode 3 (Parent Attribute) parameters instead:
\- Pass 'parentObjectType', 'parentAttributeSlug', 'condition', and 'value'
\- All functionality remains identical

This tool will be removed in version 2.0.0.

\---

Filter entries by parent record attributes (industry, role). Never search multiple lists or modify records. Requires listId, parentObjectType, parentAttributeSlug, condition, value. Use records_discover_attributes for valid slugs.

Input parameters:

- `condition` (string, required): Filter condition (e.g., "equals", "contains", "starts_with")
- `limit` (number): Maximum number of entries to fetch (default: 20)
- `listId` (string, required): UUID of the list to filter entries from
- `offset` (number): Number of entries to skip for pagination (default: 0)
- `parentAttributeSlug` (string, required): Attribute of the parent record to filter by (e.g., "name", "email_addresses", "categories")
- `parentObjectType` (string, required): Type of the parent record (e.g., "companies", "people")
- `value` (required): Value to filter by (type depends on the attribute)

### `filter-list-entries-by-parent-id` (~207 tokens)

[DEPRECATED] This tool has been consolidated into 'filter-list-entries'.

Please use 'filter-list-entries' with Mode 4 (Parent UUID) parameters instead:
\- Pass 'parentRecordId' parameter
\- Note: Parameter renamed from 'recordId' to 'parentRecordId' for consistency
\- All functionality remains identical (fastest filtering mode)

This tool will be removed in version 2.0.0.

\---

Filter entries by exact parent record UUID. Never search multiple lists. Requires list UUID, record UUID; faster than attribute filtering. Use get-record-list-memberships for workspace-wide search.

Input parameters:

- `limit` (number): Maximum number of entries to fetch (default: 20)
- `listId` (string, required): UUID of the list to filter entries from
- `offset` (number): Number of entries to skip for pagination (default: 0)
- `recordId` (string, required): UUID of the parent record to filter by

### `create-list` (~210 tokens)

Create a new CRM list (sales pipeline, recruiting tracker, support queue). Supports templates for quick setup with smart defaults. Never update existing lists or manage list entries. Requires name and parent_object. Template expansion fills defaults before validation. Dry-run mode previews without creating. Use get-lists to verify the list was created. Use update-list-configuration to modify after creation.

Input parameters:

- `attributes` (object): Additional list attributes (e.g., stages, custom fields). Merged onto template defaults if template is specified.
- `description` (string): Optional description for the list
- `dry_run` (boolean): Preview the creation without committing. Returns normalized preview of what would be created.
- `name` (string, required): Name of the list to create
- `parent_object` (string, required): Object type this list is for (e.g., "companies", "people"). Auto-validated against workspace objects.
- `template` (string): Optional template name for smart defaults. Expands before validation so errors reference actual values.

### `update-list-configuration` (~145 tokens)

Update configuration of an existing list (name, description, custom fields). Detects immutable fields and provides clear errors. Never change parent_object (immutable) or manage list entries. Requires listId. Immutable fields (parent_object) are rejected before the API call. Dry-run mode previews changes. Use get-list-details to inspect current configuration. Use create-list for a different parent_object.

Input parameters:

- `attributes` (object, required): Attributes to update. Immutable fields (parent_object) will be rejected with a clear error.
- `dry_run` (boolean): Preview the update without committing. Returns normalized preview of what would change.
- `listId` (string, required): UUID of the list to update

### `list-workspace-members` (~105 tokens)

List workspace members to plan assignments and access checks. Never change access levels or invite new members; read-only. Supports optional search, pagination (1-100 per page, default 25). Use search-workspace-members for targeted lookups.

Input parameters:

- `page` (integer): Page number (1-indexed).
- `pageSize` (integer): Number of results per page (max 100).
- `search` (string): Optional case-insensitive match on member name or email.

### `search-workspace-members` (~72 tokens)

Search workspace members by name, email, or access role. Never modify member profiles or permissions; lookup only. Requires query string (minimum 2 characters). If no results, list-workspace-members provides the full roster.

Input parameters:

- `query` (string, required): Search term for member name, email address, or role.

### `get-workspace-member` (~67 tokens)

Retrieve profile and access details for one workspace member. Never update member information or change permissions. Requires workspace_member_id from list/search results; read-only. Use list-workspace-members to confirm the memberId before retrying.

Input parameters:

- `memberId` (string, required): Workspace member ID (UUID).

## Diagnostics

Captured diagnostic sections: Provenance, Install scripts, Vulnerabilities, Dependencies. The full working is on the page: https://verifymcp.io/servers/kesslerio-attio-mcp-server/attio-mcp#diagnostics

## Score history

- 2026-08-03: 76
- 2026-08-02: 75
- 2026-08-01: 40
- 2026-07-31: 25
- 2026-07-30: 52
- 2026-07-28: 52
- 2026-07-27: 52

## Links

- npm package: https://www.npmjs.com/package/attio-mcp
- Socket report: https://socket.dev/npm/package/attio-mcp
- Repository: https://github.com/kesslerio/attio-mcp-server
- Website: https://kesslerio.github.io/attio-mcp-server
- Changelog RSS feed: https://verifymcp.io/servers/kesslerio-attio-mcp-server/attio-mcp/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/kesslerio-attio-mcp-server/attio-mcp/changelog.json
- HTML version of this page: https://verifymcp.io/servers/kesslerio-attio-mcp-server/attio-mcp
