Metadata-Version: 2.4
Name: affinity-mcp
Version: 0.4.0
Summary: Affinity MCP server
Author-email: Affinity <support@affinity.co>
License: MIT License
        
        Copyright (c) 2026 Affinity
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: affinity,crm,mcp
Classifier: Development Status :: 4 - Beta
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.13
Requires-Dist: loguru>=0.7.3
Requires-Dist: mcp[cli]>=1.25.0
Requires-Dist: opentelemetry-api>=1.40.0
Description-Content-Type: text/markdown

# affinity-mcp: An Affinity MCP Server

This package sets up the Affinity MCP server locally to interact with the Affinity APIs. Affinity now offers a hosted version. See the [setup instructions](https://developer.affinity.co/pages/mcp/setup) to get started.

- [Version 2](https://developer.affinity.co/)
- [Version 1](https://api-docs.affinity.co/)

> **Note:** When this MCP server makes requests to the Affinity API, it includes a User-Agent header that identifies the request as coming from the Affinity MCP Server. This helps the Affinity team understand API usage patterns and provide better support for MCP-specific issues.

## Features

### Persons

- **Search Persons**: Search for persons by name or email, with optional filtering by interaction dates (first/last email, meetings)
- **Get Person Info**: Retrieve detailed information about a person including current organization, job title, and more.
- **Get Person List Entries**: View which lists a person appears on
- **Create Person**: Create a new person with first name, last name, emails, and optional organization associations

### Companies

- **Search Companies**: Search for companies by name or domain, with optional filtering by interaction history
- **Get Company Info**: Retrieve detailed information about a company including location, description, and more.
- **Get Company List Entries**: View which lists a company appears on
- **Create Company**: Create a new company with a required `name` and optional `domain` and person associations via `person_ids`

### Entity Files
- **Download Entity File**: Download a file/attachment by its entity file ID and save it into the server's download sandbox

### Opportunities

- **Search Opportunities**: Search for opportunities by keyword or list all opportunities

### Semantic Search

- **Semantic Search**: Finds companies matching a natural language description about business context, characteristics, or relationship data. Support for searching on persons coming soon!

### Notes

- **Create Note**: Create an HTML note and attach it to persons, companies, or opportunities
- **Get Notes**: Find notes with filtering by ID, creator, or creation date
- **Get Notes for Entity**: Retrieve all notes attached to a specific person, company, or opportunity
- **Get Entities Attached to Note**: Find all persons, companies, or opportunities linked to a specific note

### Lists

- **Get Lists**: View all lists in your organization that you have access to
- **Get List Info**: Retrieve metadata about a specific list
- **Get List Entries**: Retrieve list entries from a specific list
- **Get Single List Entry**: Retrieve metadata about a single list entry from a specific list
- **Create List**: Create a new company, person, or opportunity list, optionally public
- **Create List Entry**: Add an existing person or company as a list entry to a specific list

### Saved Views
- **Get Saved Views**: Retrieve all saved views configured on a specific list
- **Get Saved View List Entries**: Retrieve list entries from a specific saved view, returning the fields the view is configured to display

### Meetings

- **Get Meetings**: Retrieve past and future meetings with filtering by meeting ID, start time, creation time, or update time
- **Get Meetings for Entity**: Retrieve past and future meetings for a specific company, person, or opportunity, with filtering by internal person and logging type

### Fields
- **Get Entity Fields**: View metadata about available fields for companies or persons, with optional filtering by field name
- **Get List Fields**: View metadata about available fields for a specific list, with optional filtering by field name
- **Get List Field Dropdown Options:** View metadata about available dropdown options for a list field
- **Get Entity Field Dropdown Options:** View metadata about available dropdown options for a company or person field
- **Create Field**: Create a new field (custom column) on a list or globally on an entity

### Field Values

- **Upsert Entity Field Values**: Create, update, or clear field values in bulk for a company or person
- **Upsert List Entry Field Values**: Create or update field values in bulk for a specific list entry

### Field Value Changes

- **Get Field Value Changes**: Retrieve a paginated audit log of field value changes across the org, filterable by field, list entry, changer, action type, or change time — designed for delta sync workflows

### Files

- **Get Entity Files**: Retrieve metadata for all files attached to a specific company, person, or opportunity

### Relationship Strengths

- **Get Relationship Strengths**: Retrieve relationship strengths between an external person and internal team members
- **Get Person Relationships**: Retrieve relationship strengths (V2) between a person (internal or external) and the people they interact with, with pagination and optional filtering by interaction score
- **Get Company Relationships**: Retrieve relationship strengths (V2) between your team and the people associated with a company, with pagination and optional filtering by interaction score

### Reminders

- **Get Reminders**: Get reminders with optional filtering by entity, creator, owner, completer, type, reset type, and due date
- **Create Reminder**: Create a new reminder
- **Update Reminder**: Update an existing reminder's owner, content, due date, recurrence, or completion status
- **Delete Reminder**: Delete a reminder by ID

### Transcripts

- **Get Transcript Fragments**: Get dialogue fragments from a specific transcript

### Auth

- **Get Current User**: Get information about the current user and organization

### Feedback

- **Send Feedback**: Submit feedback about a missing capability or limitation directly to Affinity

## Prerequisites

### 1. Setup API Key

Follow the steps in [this article](https://support.affinity.co/s/article/How-to-create-and-manage-API-keys#how-to-create-and-manage-api-keys) to obtain your Affinity API key.

> ⚠️ Never store your API key in `.env` files or commit it to version control. Always store it in an environment variable as shown in the configuration examples below.

### 2. Install UV

[Install UV](https://docs.astral.sh/uv/getting-started/installation/) Python package manager (recommended over pip for simpler dependency management)

## MCP Client Configuration

- [Claude](#claude)
  - [Claude CLI](#claude-cli)
  - [Claude Desktop](#claude-desktop)
- [Gemini](#gemini)
  - [Gemini CLI](#gemini-cli)
- [GitHub Copilot](#github-copilot)
  - [Copilot VSCode](#copilot-vscode)
  - [Copilot CLI](#copilot-cli)
- [Other Clients](#other-clients)

<a id="claude"></a>

### Claude Setup

<a id="claude-cli"></a>

#### Claude CLI

1. **Add server**

   Run the following command with your API key:

   ```bash
   claude mcp add affinity-mcp \
       --scope user \
       --transport stdio \
       --env AFFINITY_API_KEY=your_api_key_here \
       -- uvx affinity-mcp
   ```

2. **Verify MCP server configuration**
   1. Run command: `claude mcp list`
   2. Ensure that the following server is connected:
      `affinity-mcp: uvx affinity-mcp - ✓ Connected`

<a id="claude-desktop"></a>

#### Claude Desktop

Reference: [Connect Local MCP Servers to Claude Desktop](https://modelcontextprotocol.io/docs/develop/connect-local-servers#installing-the-filesystem-server)

1. Go to **File** → **Settings** → **Developer** → **Edit Config** and open **_claude_desktop_config.json_**.
2. Run `which uvx` in your terminal and copy the full path it returns.
3. Add the following to the config, replacing the `command` with the path from the previous step and the API key with your own:
   ```json
   {
     "mcpServers": {
       "affinity-mcp": {
         "command": "your-uvx-path-here",
         "args": ["affinity-mcp"],
         "env": {
           "AFFINITY_API_KEY": "your_api_key_here"
         }
       }
     }
   }
   ```
4. Restart Claude Desktop to apply the changes.

<a id="gemini"></a>

### Gemini Setup

Reference: [Gemini CLI MCP Configuration](https://geminicli.com/docs/tools/mcp-server/#configuration-structure)

<a id="gemini-cli"></a>

#### Gemini CLI

1. **Open settings.json**
   1. Go to **~/.gemini**
   2. Open **_settings.json_**

2. **Add server to config file**

   Add the server configurations to the config file:

   ```json
   {
     //...file contains other config objects
     "mcpServers": {
       "affinity-mcp": {
         "command": "uvx",
         "args": ["affinity-mcp"],
         "env": {
           "AFFINITY_API_KEY": "your_api_key_here"
         },
         "trust": false
       }
     }
   }
   ```

3. **Verify server is connected**
   1. Run `gemini mcp list` or run `gemini` → `/mcp`
   2. You should see your server connected:

   ```bash
   Configured MCP servers:

   ✓ affinity-mcp: uvx affinity-mcp (stdio) - Connected
   ```

<a id="github-copilot"></a>

### GitHub Copilot Setup

<a id="copilot-vscode"></a>

#### Copilot VSCode

1. **Add server through VSCode**
   1. Open the command palette by pressing `Cmd+Shift+P` (macOS) or `Ctrl+Shift+P` (Windows/Linux). You'll see a search bar appear at the top of VSCode.
   2. Type `>MCP: Add Server` in the search bar and select it from the dropdown.
   3. Select **Command (stdio)** when prompted
   4. Enter `uvx affinity-mcp` as the command
   5. Enter `affinity-mcp` as the Server ID
   6. When prompted for a configuration, choose **Global** if you want the MCP server to be available in all workspaces, or choose a specific workspace.

2. **Add API Key**
   1. You should now be able to see a new **.vscode/mcp.json** file
   2. Open it to verify the configuration.
   3. Underneath `args`, add your API key:

   ```
   "env": {
       "AFFINITY_API_KEY": "your_api_key_here"
   }
   ```

   Your configuration should look like this:

   ```json
   {
     "servers": {
       "affinity-mcp": {
         "type": "stdio",
         "command": "uvx",
         "args": ["affinity-mcp"],
         "env": {
           "AFFINITY_API_KEY": "your_api_key_here"
         }
       }
     },
     "inputs": []
   }
   ```

3. On the Copilot panel in VSCode, try asking it "What are the available tools?" and you should be able to see the available tools for Affinity MCP.

<a id="copilot-cli"></a>

#### Copilot CLI

1. **Run Copilot CLI**

2. **Add server using /mcp**
   1. Run **/mcp add**
   2. Add the server information:

   ```bash
   Server Name: affinity-mcp
   Server Type: STDIO
   Command: uvx affinity-mcp
   Environment Variables: {"AFFINITY_API_KEY": "your_api_key_here"}
   Tools: *
   ```

   3. Press CTRL + S to save.

3. **Verify configurations**
   1. Run **/mcp show** and you should see the server is connected.
   2. Open **~/.copilot/mcp_config.json** to verify.

   ```json
   {
     "mcpServers": {
       "affinity-mcp": {
         "tools": ["*"],
         "type": "stdio",
         "command": "uvx",
         "args": ["affinity-mcp"],
         "env": {
           "AFFINITY_API_KEY": "your_api_key_here"
         }
       }
     }
   }
   ```

<a id="other-clients"></a>

### Other Clients

See [MCP Clients](https://modelcontextprotocol.io/clients) for more options.

## OpenTelemetry (Optional)

The server supports OpenTelemetry tracing. To export telemetry data to an OTLP-compatible collector, set the `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable in your LLM client config alongside your API key:

```
"env": {
  "AFFINITY_API_KEY": "your_api_key_here",
  "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4317"
}
```

If `OTEL_EXPORTER_OTLP_ENDPOINT` is not set, telemetry export is disabled and the server operates normally without it.

## Download Directory (Optional)

The **Download Entity File** tool writes downloaded files into a sandbox directory on the machine running the server. By default this is the current user's `~/Downloads` folder. To write somewhere else, set the `AFFINITY_DOWNLOAD_DIR` environment variable to an absolute path in your LLM client config alongside your API key:

```
"env": {
  "AFFINITY_API_KEY": "your_api_key_here",
  "AFFINITY_DOWNLOAD_DIR": "/path/to/downloads"
}
```

Downloads are constrained to this directory: callers can request a relative subdirectory but cannot write outside the sandbox. On a remote/hosted server, files are saved on that server, not on the caller's machine.

## Troubleshooting

### View Server Logs

If the server isn't working as expected, you can view the logs to debug issues.

**macOS (Claude Desktop):**
Open a terminal and run:

```bash
tail -n 20 -F ~/Library/Logs/Claude/mcp*.log
```

**Windows (Claude Desktop):**
Logs are typically located in `%APPDATA%\Roaming\Claude\logs`.

### Common Issues

#### 1. "Authentication failed" or 401 Errors

- **Cause:** The `AFFINITY_API_KEY` environment variable is missing or invalid.
- **Fix:** Double-check your API key. Ensure there are no extra spaces or quotes around the key.

#### 2. "Connection refused" or Timeout

- **Cause:** The server cannot reach `api.affinity.co`.
- **Fix:**
  - Check your internet connection.
  - If you are on a corporate VPN, ensure it allows traffic to Affinity's API.

#### 3. Changes to API key not taking effect

- **Cause:** Claude Desktop loads environment variables when it starts.
- **Fix:** You must **fully quit and restart** Claude Desktop.

#### 4. "Tool not found"

- **Cause:** The MCP server might have crashed or failed to start.
- **Fix:** Check the logs (see above) for startup errors.

## Security

The MCP server acts as a wrapper around the Affinity APIs and does not create a new data access mechanism. The trust boundary and access controls remain at the API layer.

### Vulnerability Reporting

If you discover a security vulnerability, please refer to our [Security Policy](https://www.affinity.co/bounty) for more information about the disclosure procedure.

### Software Bill of Materials (SBOM)

A Software Bill of Materials (SBOM) is automatically generated and included with each release for compliance and security auditing purposes. The SBOM provides a complete inventory of all dependencies and their versions in CycloneDX JSON format.

**Access the SBOM:**

**Option 1: Download from PyPI website**

1. Visit the [PyPI package page](https://pypi.org/project/affinity-mcp/)
2. Navigate to the **Download files** tab
3. Download the `.tar.gz` source distribution file
4. Extract and view the SBOM:
   ```bash
   tar -xzf affinity_mcp-{version}.tar.gz
   cat affinity_mcp-{version}/src/affinity_mcp/affinity-mcp-{version}-sbom.json
   ```

**Option 2: Use pip to download**

```bash
pip download affinity-mcp --no-deps --no-binary :all:
tar -xzf affinity_mcp-*.tar.gz
cat affinity_mcp-*/src/affinity_mcp/affinity-mcp-*-sbom.json
```

The SBOM can be used with security scanning tools to audit dependencies and identify potential vulnerabilities.

## Terms of Use

This MCP server is governed by [Affinity's Terms of Use](https://www.affinity.co/legal/terms-of-use). By using this server, you agree to comply with these terms.
