create_list_entry
ChatGPTAdds an existing company or person as a list entry on the specified list. Opportunities CANNOT be added using this tool. Args: list_id: ID of the list where the entry is being added. entity_id: ID of the existing person or company to add to this list. Returns: JSON object containing information about the newly created list entry.
create_note
ChatGPTCreates a new HTML note with the supplied parameters. REQUIRED: - content: The note content (cannot be empty) - At least one of: person_ids, organization_ids, or opportunity_id Args: person_ids: List of person IDs company_ids: List of company IDs opportunity_ids: List of opportunity IDs content (str): HTML content of the note. Common formatting options: - <strong> for bold, <em> for italic, <u> for underline - <ul><li> for bullet lists, <ol><li> for numbered lists - <blockquote> for block quotes - <hr> for dividers Returns: dict[str, Any]: API response containing the created note information
create_reminder
ChatGPTCreates a new reminder. SCHEDULING BY DAY NAME: If the user specifies a recurring reminder by day name (e.g. "every Friday", "every Sunday"), calculate the next occurrence of that day from today's date and use it as the due_date for the first reminder. Set reminder_days to match the recurrence interval (e.g. 7 for weekly, 14 for bi-weekly). You must still supply reset_type and the other recurring fields documented under reset_type and reminder_days below; this section only helps derive due_date and reminder_days. Args: owner_id: Required. Internal person ID who owns the reminder (team member only; not an external contact). reminder_type: Required. ReminderType.ONE_TIME (0) or ReminderType.RECURRING (1). If unclear, ask before calling. entity_id: Required with entity_type. ID of the company, external/collaborator person, or opportunity to attach the reminder to. If the user has not chosen a target yet, ask before calling. entity_type: Required with entity_id. Options: 0 = company, 1 = person, 8 = opportunity. content: Optional description or note text for the reminder. due_date: Required when reminder_type is ONE_TIME; omit for recurring unless you are supplying a first due date (e.g. day-name scheduling). ISO 8601. If the user has not given a due date for a one-time reminder, ask before calling. Example: "2025-01-31T00:00:00Z" reset_type: Required when reminder_type is RECURRING. What triggers the reset: ReminderResetType.INTERACTION (0), EMAIL (1), or EVENT (2). If missing, ask before calling. reminder_days: Required when reminder_type is RECURRING; minimum 1. If missing, ask before calling. is_completed: Optional; only for ONE_TIME. Whether the reminder is completed on creation. Do not pass for RECURRING (the API rejects it). Returns: dict[str, Any]: API response containing the created reminder.
delete_reminder
ChatGPTDeletes a reminder by ID. Requires the current user to be either the creator OR owner of the reminder, otherwise the API returns a permissions error. Args: reminder_id: The ID of the reminder to delete. Returns: JSON object containing confirmation of successful deletion.
get_company_info
ChatGPTReturns basic information and non-list specific field data on the requested company. By default, returns all field data including location, description, and more. Use get_entity_fields tool if you need to filter to specific fields. IMPORTANT: field_ids and field_types are mutually exclusive. They cannot be used together. Args: company_id (required): The ID of the company field_ids: List of field IDs to return. field_types: List of field types to return. Defaults to ['enriched', 'global', 'relationship-intelligence'] Returns: Metadata about the specified company including field data
get_company_list_entries
ChatGPTFetches list entries for the given company. Args: company_id (required): The ID of the company cursor: Cursor for the next or previous page. limit: The number of items to include in the page. Default is 100 Returns: Structured data containing the matching list entries
get_current_user
ChatGPTGet information about the current user. Use this tool to verify authentication and understand available API access levels. Returns: Information about the user, their current organization, and API key permissions.
get_entities_attached_to_note
ChatGPTFind entities attached to a note. Allows to retrieve details of a note, or a list of entities that are directly attached to a note. Args: note_id: The note ID that will be used in the search entity_type: Type of entities to retrieve. Options: 0 = company, 1 = person, 8 = opportunity.
get_entity_field_values
ChatGPTGet field values for an entity. Use this tool if the entity is NOT on a list. If the entity is on a list, and you have the list context, prefer get_single_list_entry tool. Args: entity_type: Type of entity. Options: 0 = company, 1 = person, 8 = opportunity. entity_id: ID of the entity Returns: List of JSON objects containing field value data
get_entity_fields
ChatGPTReturns metadata on non-list specific company or person fields. Args: entity_type: Type of entity to return fields for. Options: 0 = company, 1 = person cursor: Cursor for the next or previous page. limit: The number of items to include in the page. Default is 100. Returns: Field metadata
get_list_entries
ChatGPTPaginate through list entries on a given list. Each list entry contains basic information about the related person/company/opportunity and list-specific field data. By default, returns only list-specific fields. IMPORTANT: field_ids and field_types are mutually exclusive. They cannot be used together. WARNING: Lists can contain many entries with large field data. Best practices to minimize response size: - MUST start with limit=10 (default), increase only if needed - Select specific fields using field_ids or field_types (use get_list_fields tool to identify fields) - Request additional field types (enriched, global, relationship-intelligence) only when needed - Use pagination (cursor) to iterate through results Args: list_id (required): ID of list cursor: Cursor for the next or previous page. limit: The number of items to include in the page. Default is 10, maximum is 100. field_ids: List of field IDs to return. field_types: List of field types to return. Defaults to ['list']. Available types: 'enriched', 'global', 'relationship-intelligence', 'list' Returns: List of JSON objects containing list entry metadata such as entity info and list-specific field data.
get_list_field_dropdown_options
ChatGPTReturns the dropdown options for a specific dropdown or ranked-dropdown field on a list. Use the returned dropdown option IDs when writing dropdown field values via upsert_list_entry_field_values and upsert_entity_field_value (ranked-dropdown only). Args: list_id: ID of list field_id: human-readable string ID of field to return options for (ex. "field-123") cursor: Cursor for the next or previous page. limit: The number of items to include in the page. Default is 20, maximum is 100. Returns: Metadata about each dropdown option
get_list_fields
ChatGPTReturns metadata on fields available for a given list. Args: list_id: ID of list to return fields for. cursor: Cursor for the next or previous page. limit: The number of items to include in the page. Default is 100. Returns: Field metadata
get_list_info
ChatGPTGet metadata on a single list Args: list_id (required): ID of list Returns: JSON object containing list metadata such as list name, entity type, creator ID, and owner ID.
get_lists
ChatGPTGet all lists in the user's organization that they have access to Args: cursor: Cursor for the next or previous page. limit: The number of items to include in the page. Default is 100. Returns: List of JSON objects containing list metadata such as list name, entity type, creator ID, and owner ID.
get_meetings
ChatGPTGet information about past and future meeting interactions and their attendees. Args: filter_expr: Filter expression using Affinity query language. Available fields: - id: unique identifier for the meeting (operators: =) Example: "id=1" or "(id=1 | id=2)" - startTime: When the meeting was scheduled (operators: >, <, >=, <=) Format: ISO 8601 timestamp Example: "startTime>2025-01-01T01:00:00Z" - createdAt: When the meeting was created in Affinity (operators: >, <, >=, <=) Format: ISO 8601 timestamp Example: "createdAt>=2025-01-01T00:00:00Z" - updatedAt: When the meeting was last updated (operators: >, <, >=, <=) Format: ISO 8601 timestamp Example: "updatedAt<=2025-12-31T23:59:59Z" Complex examples: - Date range: "startTime>=2025-01-01T00:00:00Z & startTime<2025-02-01T00:00:00Z" - Multiple date filters: "startTime>2025-01-01T00:00:00Z & createdAt>=2024-12-01T00:00:00Z" Boolean logic: & (AND), | (OR), () for grouping Full filtering spec: https://developer.affinity.co/pages/external-api-v2/filtering cursor: Cursor for the next or previous page. limit: Number of items to include in the page. Default is 20, max is 100. Returns: Structured data containing the list of meetings and pagination information. Raises: MeetingsV2AccessError: If the user does not have access to V2 meetings endpoint
get_meetings_for_entity
ChatGPTGet information about meetings for a specific company, person, or opportunity. IMPORTANT: The date range between start_time and end_time cannot exceed 365 days. Be mindful of leap years. Args: entity_id: The ID of the company, external person, or opportunity entity_type: What type of entity this ID refers to. Options: 0 = company, 1 = person, 8 = opportunity start_time: ISO 8601 formatted timestamp to filter meetings starting from this time. Must be before end_time Format: "2025-01-01T00:00:00Z" end_time: ISO 8601 formatted timestamp to filter meetings ending before this time. Must be after start_time Format: "2025-01-01T00:00:00Z" Maximum 365 day range examples: ✓ VALID: start_time: "2025-02-25T00:00:00Z", end_time: "2026-02-25T00:00:00Z" ✓ VALID: start_time: "2025-01-01T00:00:00Z", end_time: "2025-12-31T23:59:59Z" ✓ VALID (leap year): start_time: "2024-01-01T00:00:00Z", end_time: "2024-12-31T00:00:00Z" (365 days, not 366) ✗ INVALID: start_time: "2025-02-25T00:00:00Z", end_time: "2026-02-25T23:59:59Z" (exceeds 1 year by 23:59:59) internal_person_id: ID of an internal person that was involved in the meetings. This parameter filters down the set of interactions related to the given entity to only those in which this internal person was involved. Cannot be used to find all of an internal person's interactions. logging_type: Filter by logging classification. When not supplied, returns all logging types. Options: - LoggingType.ALL (0): Both automatically and manually logged interactions - LoggingType.MANUAL (1): Only manually logged interactions page_size: Number of results per page. Default is 10, maximum is 100. page_token: The next_page_token from the previous response required to retrieve the next page of results. Returns: Structured data containing an array of meetings and pagination for retrieving more results
get_notes
ChatGPTFind notes in Affinity. Filter by ID, creator, and/or creation date. Args: filter_expr: Filter expression using Affinity query language. Available fields: - id: unique identifier for the note (operators: =) Example: "id=123" or "(id=1 | id=2 | id=10)" - creator.id: Person ID that created the note (operators: =) Example: "creator.id=456" - createdAt: When the note was created in Affinity (operators: >, <, >=, <=) Format: ISO 8601 timestamp Example: "createdAt>=2026-01-01T00:00:00Z" Complex examples: - Date range: "createdAt>=2026-01-01T00:00:00Z & createdAt<2026-02-01T00:00:00Z" - By creator in date range: "creator.id=123 & createdAt>=2026-01-01T00:00:00Z" Boolean logic: & (AND), | (OR), () for grouping Full filtering spec: https://developer.affinity.co/pages/external-api-v2/filtering cursor: Cursor for the next or previous page. limit: Number of items to include in the page. Default is 20, max is 100. When you need more than 100 records, use the cursor to paginate over the results. Returns: Structured data containing the list of notes and pagination information.
get_notes_for_entity
ChatGPTGet all notes attached to a specific company, person, or opportunity. For the reverse (finding entities attached to a note), use get_entities_attached_to_note. Args: entity_id: The ID of the company, person, or opportunity entity_type: What type of entity this ID refers to. Options: 0 = company, 1 = person, 8 = opportunity Example: To get notes for company ID 123, use entity_id=123, entity_type=0
get_person_info
ChatGPTReturns basic information and non-list specific field data on the requested person. By default, returns all field data including current organization, job title, and more. Use get_entity_fields tool if you need to filter to specific fields. IMPORTANT: field_ids and field_types are mutually exclusive. They cannot be used together. Args: person_id (required): The ID of the person field_ids: list of field IDs to return. field_types: List of field types to return. Defaults to ['enriched', 'global', 'relationship-intelligence'] Returns: Metadata about the specified person including field data
get_person_list_entries
ChatGPTFetches list entries for the given person. Args: person_id (required): The ID of the person cursor: Cursor for the next or previous page. limit: The number of items to include in the page. Default is 100 Returns: Structured data containing the matching list entries
get_relationship_strengths
ChatGPTGets relationship strengths between an external person and internal team members. Optionally filter to a specific internal person. IMPORTANT: When the user uses first-person language (ex. 'my relationship', 'how do I know', etc.), you MUST call get_current_user first to obtain the internal_person_id. Args: external_person_id: ID of the external person to get relationship strengths for internal_person_id: Optional ID to filter results to a specific internal person Returns: A list of relationship strength records, each containing external_id, internal_id, and strength represented as a float between 0-1. You MUST convert the strength to a percentage between 0 and 100, rounded to the nearest integer (values of .5 or greater round up, values less than .5 round down)
get_reminders
ChatGPTReturns reminders that meet the query parameters if provided. By default, returns reminders for all entities. IMPORTANT: entity_id and entity_type are only applied when both are provided; if only one is set, the entity filter is ignored and reminders for all entities are returned. Args: entity_id: The ID of the company, external person, or opportunity to filter reminders by. entity_type: The type of entity that entity_id refers to. Options: 0 = company, 1 = person, 8 = opportunity. creator_id: Filters to reminders created by this internal person (identified by their person ID). owner_id: Filters to reminders assigned to this internal person (identified by their person ID). completer_id: Filters to reminders completed by this internal person (identified by their person ID). reminder_type: Filters by recurrence type: - ReminderType.ONE_TIME (0): One-time reminders only - ReminderType.RECURRING (1): Recurring reminders only reset_type: Filters recurring reminders by their reset trigger. Only valid when reminder_type=RECURRING. - ReminderResetType.INTERACTION (0): Resets on any interaction - ReminderResetType.EMAIL (1): Resets on email only - ReminderResetType.EVENT (2): Resets on event only status: Filters by reminder status: - ReminderStatus.COMPLETED (0): Completed reminders - ReminderStatus.ACTIVE (1): Active reminders - ReminderStatus.OVERDUE (2): Overdue reminders due_before: ISO 8601 formatted date to retrieve reminders due before this date. Example: "2025-01-31T00:00:00Z" due_after: ISO 8601 formatted date to retrieve reminders due after this date. Example: "2025-01-01T00:00:00Z" page_size: Number of results per page. Default is 10. page_token: The next_page_token from the previous response required to retrieve the next page of results. Returns: Structured data containing the list of reminders and pagination information.
get_single_list_entry
ChatGPTRetrieve a single list entry from the given list. The list entry contains basic information about the related person/company/opportunity and list-specific field data. By default, returns only list-specific fields. IMPORTANT: field_ids and field_types are mutually exclusive. They cannot be used together. WARNING: List entry may contain large field data. Best practices to minimize response size: - Select specific fields using field_ids or field_types (use get_list_fields tool to identify fields) - Request additional field types (enriched, global, relationship-intelligence) only when needed Args: list_id (required): ID of list list_entry_id (required): ID of list entry field_ids: List of field IDs to return. field_types: List of field types to return. Defaults to ['list']. Available types: 'enriched', 'global', 'relationship-intelligence', 'list'
get_transcript_fragments
ChatGPTGet dialogue fragments (individual speaker turns) from a transcript. Use pagination to retrieve all fragments from long transcripts. To get transcripts for a specific entity (company, person, opportunity): 1. Use get_notes_for_entity to get notes for that entity 2. Look for notes where type is "ai-notetaker" or "ai-notetaker-reply" 3. Those notes have a transcriptId field - use it with this tool Args: transcript_id: The transcript ID from the transcriptId field in AI Notetaker notes (returned by get_notes_for_entity). cursor: Cursor for the next or previous page. limit: Number of items per page. Default is 20, max is 100. Returns: Paginated list of dialogue fragments with total count. Each fragment contains speaker, content, and timestamps.
search_companies
ChatGPTSearches for companies by name or domain, with optional filtering on interaction dates. For natural language or characteristic-based queries (e.g., "AI startups", "companies like OpenAI", "biotech firms"), use semantic_search() instead. Args: term: A string used to search all the organizations in your team's address book. This could be a name or a domain name. with_interaction_dates: When true, interaction dates will be present on the returned resources. Only organizations that have interactions will be returned. with_interaction_persons: When true, persons for each interaction will be returned. Used in conjunction with with_interaction_dates. with_opportunities: When true, opportunity IDs associated with this organization will be returned. date_filters: Optional dictionary to filter by interaction dates. Keys can be 'min_first_email_date', 'max_last_interaction_date', etc. Dates must be in ISO 8601 format (e.g. '2024-01-01T12:00:00Z'). page_size: Number of results per page. If not specified, defaults to 10 when searching with a term, otherwise 100. page_token: The next_page_token from the previous response required to retrieve the next page of results. Returns: Structured data containing the list of matching companies and pagination token.
search_opportunities
ChatGPTSearch for opportunities or list them with optional filters. Args: term: Search term used to search through opportunities page_size: Number of results per page. If not specified, defaults to 10 when searching with a term, otherwise 100. page_token: Pagination token for next page of results Returns: dict[str, Any]: API response containing information on list of opportunities
search_persons
ChatGPTSearches for persons in the Affinity CRM by name or email. Also allows filtering persons based on their interaction history, such as the dates of the first/last emails or meetings. Args: term: A string used to search all the persons in your team's address book. This could be an email address, a first name or a last name. with_interaction_dates: When true, interaction dates will be present on the returned resources. Only persons that have interactions will be returned. with_interaction_persons: When true, persons for each interaction will be returned. Used in conjunction with with_interaction_dates. with_opportunities: When true, opportunity IDs will be returned for each person. with_current_organizations: When true, the organization IDs of each person's current organizations (according to the Affinity Data: Current Organizations column) will be returned. date_filters: Optional dictionary to filter by interaction dates. Keys can be 'min_first_email_date', 'max_last_interaction_date', etc. Dates must be in ISO 8601 format (e.g. '2024-01-01T12:00:00Z'). page_size: Number of results per page. If not specified, defaults to 10 when searching with a term, otherwise 100. page_token: The next_page_token from the previous response required to retrieve the next page of results. Returns: Structured data containing the list of matching persons and pagination token.
semantic_search
ChatGPTFinds companies matching a natural language description about business context, characteristics, or relationship data. If looking up a company by keyword or domain, use search_companies instead. SEARCHABLE ATTRIBUTES: - Industry/sector: "healthcare", "fintech", "climate tech", "enterprise SaaS", "biotech", "AI" Example: "climate tech companies in our pipeline" - Technology/business concepts: "solar energy", "battery storage", "payment processing", "gene therapy" Example: "biotech companies working on extracellular vesicles" - Funding information: stage, funding date, amount raised, year founded Example: "Series A companies that raised more than $10M" - Employee metrics: headcount, hiring/departure rates Example: "companies with more than 100 employees" - Interaction history: search by when your firm met with or emailed companies Example: "companies we emailed recently" - Relationship strength: firm-wide relationship scores Example: "companies where we have strong connections" - Time references: "last week", "recently", "this quarter", "in the past 6 months", "90 days" Example: "companies our firm met with in the past 90 days" - Headquarters location: cities, states, countries, regions Example: "fintech startups in San Francisco" - Investor information: VC/PE firm names Example: "companies backed by Sequoia Capital" LIST FILTERING: - Use list_ids to scope results to companies that are members of specific Affinity lists. - Combine with the prompt to semantically search within a list: Example: "AI companies" with list_ids=[123] → AI companies on list 123 - Use get_lists to discover list IDs. Maximum 100 list IDs per request. SORTING: - Results can be ordered by a single sortable attribute. Cannot sort by multiple attributes. (ex. cannot sort by both total funding and last funding) - Sorting works with or without semantic descriptors: Without descriptors: "Find Series B companies with the most funding" → matches on investment stage and applies sorting for funding With descriptors: "Find Series B cancer diagnosis healthtech companies with the most funding" → optimizes for both semantic relevance and the desired sort order - Formulas and computed sorts are NOT supported (ex., "last funding / total funding") GOTCHAS: - "I", "we", and "our firm" all refer to FIRM-WIDE data. Semantic search does not support personal/individual interaction filtering. "Companies I met with last week" means "companies any member of my firm met with last week." - "In our pipeline" and "in our network" filter to org-relevant companies (companies your firm has interacted with or added to Affinity). They do NOT search for membership in a specific list named "Pipeline" or similar. To search within a specific named list, use get_lists to find its ID and pass it via list_ids. - Interaction and relationship data is always firm-wide. You cannot search by a specific team member's individual relationship or interaction history. NOT SUPPORTED: - Third-party enrichment data such as Crunchbase, PitchBook, Dealroom - Company valuation and revenue metrics - Lookup by similarity to a named company: "companies like OpenAI" - Notes, email body content, or file attachments - Custom fields you've created Args: prompt: Natural language description of the companies to find. Must be between 1 and 500 characters. limit: Number of companies to return. Default is 10. Minimum is 1, maximum is 100. list_ids: Optional list of Affinity list IDs to restrict results to. Maximum 100 IDs. Returns: A list of entities that match the prompt with an explanation of the search. Results prioritize org-relevant companies (companies your firm knows) but also search the universal database.
send_feedback
ChatGPTSends feedback to Affinity about MCP server improvements or additions. IMPORTANT: Use this tool when you cannot fulfill the user's request due to limitations in the current toolset. You MUST immediately offer to submit feedback about the missing capability. Use HTML formatting for the body. Returns: No content if the request was successful
update_reminder
ChatGPTUpdates an existing reminder. IMPORTANT: - Only the fields provided will be updated; omitted fields remain unchanged. - Updates require the current user to be either the creator OR owner of the reminder, otherwise the API returns a permissions error. Args: reminder_id: The ID of the reminder to update. owner_id: Internal person ID to reassign the reminder to. reminder_type: ReminderType.ONE_TIME (0) or ReminderType.RECURRING (1). content: Description or note text for the reminder. due_date: ISO 8601 due date. Required when reminder_type is ONE_TIME. Example: "2025-01-31T00:00:00Z" reset_type: What triggers reset for recurring reminders. Required when reminder_type is RECURRING. ReminderResetType.INTERACTION (0), EMAIL (1), or EVENT (2). reminder_days: Recurrence interval in days. Required when reminder_type is RECURRING. Minimum 1. is_completed: Whether the reminder is completed. Only for ONE_TIME, Do not pass for RECURRING (the API rejects it). Returns: dict[str, Any]: API response containing the updated reminder.
upsert_entity_field_value
ChatGPTUpsert a field value for an entity. Use this tool if the entity is NOT on a list. If the entity is on a list, and you have list context, prefer upsert_list_entry_field_values tool. This tool has two modes of operation: 1. UPDATE MODE (provide field_value_id): - Updates an existing field value with the new value - Clears the field if value=None. Note that after clearing, the field_value_id no longer exists. You must use CREATE mode to set the value again. - For multi-value fields: updates only the specific field_value_id in place - Example: upsert_entity_field_value(value=200, field_value_id=12345) 2. CREATE MODE (provide field_id + entity_id): - Creates a new field value, cannot be empty - For multi-value fields: adds a new value without affecting existing ones - For single-value fields: sets the initial value (errors if already exists) - Example: upsert_entity_field_value(value=200, field_id=456, entity_id=789) Args: value: New value. Structure depends on field type: - dropdown: str representing dropdown value, NOT option ID (ex. "In Progress") - ranked-dropdown: int representing dropdown option ID (ex. 123). Use get_list_field_dropdown_options to obtain the ID - number: int (ex. 1000000) - person: int representing person ID (ex. 1) - company: int representing company ID (ex. 2) - location: Location (ex. Location(city="San Francisco", state="CA")) - datetime: str in ISO 8601 format (ex. "2023-01-01T00:00:00Z") - text: str (ex. "Some new text") - None: clears/empties the field (only valid in UPDATE mode) field_value_id: ID of the field value field_id: ID of the field entity_id: ID of the person, company, or opportunity Returns: JSON object containing the upserted field value Raises: ValueError: if field_id, entity_id, and field_value_id are all provided
upsert_list_entry_field_values
ChatGPTUpsert up to 100 field values for a list entry. Args: list_id: ID of list list_entry_id: ID of list entry upserts: List of field value upserts. Each item has: - id (str): The field ID. Use get_list_fields or get_single_list_entry tools to discover field IDs. - value (ValueToUpsert): An object with type and data keys. Use get_list_field_dropdown_options to look up dropdown option IDs. Examples: - Text field {"id": "affinity-data-description", "value": {"type": "text", "data": "Top prospect"}} - Number field {"id": "my-revenue-field", "value": {"type": "number", "data": 5000000}} - Ranked-dropdown field (get option IDs from get_list_field_dropdown_options) {"id": "my-stage-field", "value": {"type": "ranked-dropdown", "data": {"dropdownOptionId": 42}}} - Person-multi field {"id": "my-owners-field", "value": {"type": "person-multi", "data": [{"id": 101}, {"id": 202}]}} Returns: Dict containing the name of the successful operation