# io.usefulapi/less-annoying-crm (remote · less-annoying-crm.usefulapi.io)

Read and write Less Annoying CRM contacts, notes, tasks, events, pipelines and groups.

- Trust score: 76/100 (medium)
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-10-04

## Components

- remote · `less-annoying-crm.usefulapi.io`: 76/100 (this document), [markdown](https://verifymcp.io/servers/io-usefulapi-less-annoying-crm/less-annoying-crm.md), [page](https://verifymcp.io/servers/io-usefulapi-less-annoying-crm/less-annoying-crm)

## Channel facts

- Endpoint: `https://less-annoying-crm.usefulapi.io/mcp`
- Transports: `streamable-http`
- Auth: `none`
- Version: `1.0.0`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, 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-10-04.

- **Endpoint Security**: 89/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation is enforced on tool calls, advertised via RFC 9728 protected-resource metadata. Discovery is public, which costs nothing: no tool can be invoked without a token.
  - HTTPS is enforced; there's no plaintext access path.
  - HSTS check failed: the Strict-Transport-Security header is absent.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
  - The authorisation server offers only Dynamic Client Registration (RFC 7591), which MCP 2026-07-28 deprecated in favour of Client ID Metadata Documents.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 73/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 3568 tokens (~155/item across 23 items; 23 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 7/100
  - Stability observed for 2 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 99/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 97% of tool parameters carry a description.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 23 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 23 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 60/100
  - Spec-recency check failed: implements MCP spec 2025-06-18; the latest is 2026-07-28.

## Install

### How do I install the io.usefulapi/less-annoying-crm MCP server?

io.usefulapi/less-annoying-crm is a hosted endpoint at https://less-annoying-crm.usefulapi.io/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add --transport http io-usefulapi-less-annoying-crm 'https://less-annoying-crm.usefulapi.io/mcp'
```

### Cursor

```json
{
  "mcpServers": {
    "io-usefulapi-less-annoying-crm": {
      "url": "https://less-annoying-crm.usefulapi.io/mcp"
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "io-usefulapi-less-annoying-crm": {
      "type": "http",
      "url": "https://less-annoying-crm.usefulapi.io/mcp"
    }
  }
}
```

### Codex

```toml
[mcp_servers.io-usefulapi-less-annoying-crm]
url = "https://less-annoying-crm.usefulapi.io/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "io-usefulapi-less-annoying-crm": {
      "type": "remote",
      "url": "https://less-annoying-crm.usefulapi.io/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add io-usefulapi-less-annoying-crm --url 'https://less-annoying-crm.usefulapi.io/mcp' --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  io-usefulapi-less-annoying-crm:
    url: "https://less-annoying-crm.usefulapi.io/mcp"
```

### Netclaw

```json
{
  "McpServers": {
    "io-usefulapi-less-annoying-crm": {
      "Transport": "http",
      "Url": "https://less-annoying-crm.usefulapi.io/mcp"
    }
  }
}
```

### Vellum

```bash
assistant mcp add io-usefulapi-less-annoying-crm -t streamable-http -u 'https://less-annoying-crm.usefulapi.io/mcp'
```

### Other

```json
{
  "mcpServers": {
    "io-usefulapi-less-annoying-crm": {
      "type": "http",
      "url": "https://less-annoying-crm.usefulapi.io/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## 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-10-04 (score 76, +1)

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

### 2026-10-03 (score 75, 0)

- [functional improvement] Stability: unverified → 0.03

### 2026-10-02 (score 75, +57)

- [security improvement] HTTPS: unverified → pass
- [security improvement] Authorization: unverified → pass
- [security improvement] Injection markers: unverified → pass
- [security improvement] Transport: fail → pass
- [security] First check of Judged manipulation: pass
- [security] First check of Authorization: partial
- [functional regression] MCP protocol: unverified → fail
- [functional improvement] Tool coverage: unverified → 100
- [functional] First check of Schema quality: fail
- [functional] First check of Tool coverage: 97
- [functional] First check of Schema quality: excellent
- [functional] First check of Destructive annotations: pass
- [functional] First check of Schema quality: fail

### 2026-09-29 (score 18)

First indexed and scored.

## MCP tools (23)

### `lacrm_get_user` (~54 tokens)

Get the current user

Return the user who owns this API key — UserId, name, email and timezone. A cheap way to confirm the key works, and the UserId to use for AssignedTo. LACRM: GetUser.

### `lacrm_list_users` (~48 tokens)

List users

List the users on the account that you can see (admins see all), with their UserIds — needed to assign contacts, tasks or filter by owner. LACRM: GetUsers.

### `lacrm_search_contacts` (~228 tokens)

Search contacts and companies

Search (or list) contacts and companies. With no search_terms, returns everything visible, paged. Returns { HasMoreResults, Results }. LACRM: GetContacts.

Input parameters:

- `advanced_filters` (array): AdvancedFilters, ANDed together. See https://account.lessannoyingcrm.com/api_docs/v2/Advanced/Filter_Contacts for the names/operations your account supports.
- `max_results` (integer): Results per page (MaxNumberOfResults), 1-10000. Default here: 50.
- `owner_user_ids` (array): Only records assigned to these UserIds.
- `page` (integer): Page number, 1-based. Default 1.
- `record_type` (string): Limit to people (Contacts) or Companies.
- `requires_write_access` (boolean): Only records you can edit.
- `search_terms` (string): Text to search for across record fields (name, email, phone, company...).
- `sort_by` (string): Sort field. Default Relevance.
- `sort_direction` (string): Sort direction.

### `lacrm_get_contact` (~65 tokens)

Get a contact or company

Fetch one contact or company record with all its fields (emails, phones, addresses, custom fields, owner). LACRM: GetContact.

Input parameters:

- `contact_id` (string, required): The contact or company id (a long numeric Uid — always pass it as a string).

### `lacrm_list_notes` (~181 tokens)

List notes

List notes, newest first by default — across the whole CRM, or for one contact. Filter by date range and author. LACRM: GetNotes.

Input parameters:

- `contact_id` (string): Only notes attached to this contact (a long numeric Uid — always pass it as a string).
- `date_end` (string): Only notes on/before this date-time (ISO 8601).
- `date_start` (string): Only notes on/after this date-time (ISO 8601).
- `max_results` (integer): Results per page (MaxNumberOfResults), 1-10000. Default here: 50.
- `page` (integer): Page number, 1-based. Default 1.
- `sort_direction` (string): Sort direction.
- `user_ids` (array): Only notes entered by these UserIds.

### `lacrm_list_tasks` (~196 tokens)

List tasks

List tasks due in a date range, optionally only incomplete/complete, for given users. If contact_id is given, ALL of that contact's tasks are returned regardless of dates or status. LACRM: GetTasks.

Input parameters:

- `completion_status` (string): Default Both.
- `contact_id` (string): Only tasks attached to this contact (a long numeric Uid — always pass it as a string).
- `end_date` (string, required): Upper bound of due dates, yyyy-mm-dd.
- `max_results` (integer): Results per page (MaxNumberOfResults), 1-10000. Default here: 50.
- `page` (integer): Page number, 1-based. Default 1.
- `sort_direction` (string): Sort direction.
- `start_date` (string, required): Lower bound of due dates, yyyy-mm-dd.
- `user_ids` (array): Only tasks assigned to these UserIds.

### `lacrm_list_events` (~213 tokens)

List calendar events

List calendar events in a date range, filterable by user or calendar. If contact_id is given, all events attached to that contact are returned and other filters are ignored. LACRM: GetEvents.

Input parameters:

- `calendar_ids` (array): Only events on these CalendarIds (your own calendars only).
- `contact_id` (string): Only events attached to this contact (a long numeric Uid — always pass it as a string).
- `end_date` (string): End of the range (inclusive), ISO 8601 date or date-time.
- `max_results` (integer): Results per page (MaxNumberOfResults), 1-10000. Default here: 50.
- `page` (integer): Page number, 1-based. Default 1.
- `sort_direction` (string): Sort direction.
- `start_date` (string): Start of the range (inclusive), ISO 8601 date or date-time.
- `user_ids` (array): Only events for these UserIds.

### `lacrm_list_pipelines` (~107 tokens)

List pipelines

List the account's pipelines (e.g. Sales Leads) with their statuses (StatusId, Name, IsActive) and optionally their custom fields. This is the setup, not the items — use lacrm_list_pipeline_items for those. LACRM: GetPipelines.

Input parameters:

- `include_archived` (boolean): Include deleted pipelines. Default false.
- `include_custom_fields` (boolean): Include each pipeline's custom field definitions. Default here: false (they are verbose).

### `lacrm_list_pipeline_items` (~224 tokens)

List pipeline items

List the items in one pipeline (deals, leads...), optionally only in given statuses or for given users. An empty status filter returns items in all ACTIVE statuses. LACRM: GetPipelineItems.

Input parameters:

- `advanced_filters` (array): AdvancedFilters, ANDed together. See https://account.lessannoyingcrm.com/api_docs/v2/Advanced/Filter_Contacts for the names/operations your account supports.
- `max_results` (integer): Results per page (MaxNumberOfResults), 1-10000. Default here: 50.
- `page` (integer): Page number, 1-based. Default 1.
- `pipeline_id` (string, required): The pipeline id (from lacrm_list_pipelines) (a long numeric Uid — always pass it as a string).
- `sort_by` (string): Default Status.
- `sort_direction` (string): Sort direction.
- `status_ids` (array): Only items in these StatusIds.
- `user_ids` (array): Only items whose contact is assigned to these UserIds.

### `lacrm_get_contact_pipeline_items` (~63 tokens)

Get a contact's pipeline items

All pipeline items attached to one contact or company, grouped by pipeline. LACRM: GetPipelineItemsAttachedToContact.

Input parameters:

- `contact_id` (string, required): The contact or company id (a long numeric Uid — always pass it as a string).

### `lacrm_list_groups` (~105 tokens)

List groups

List the contact groups you can see (GroupId, Name, Sharing, Color), optionally with member counts. LACRM: GetGroups.

Input parameters:

- `include_contact_counts` (boolean): Also return the number of contacts in each group (slower).
- `max_results` (integer): Results per page (MaxNumberOfResults), 1-10000. Default here: 50.
- `page` (integer): Page number, 1-based. Default 1.

### `lacrm_list_contacts_in_group` (~135 tokens)

List contacts in a group

List the contacts that are members of one group. Identify the group by group_id (preferred) or group_name — not both. LACRM: GetContactsInGroup.

Input parameters:

- `group_id` (string): The group id (a long numeric Uid — always pass it as a string).
- `group_name` (string): The group name, if you do not have its id.
- `max_results` (integer): Results per page (MaxNumberOfResults), 1-10000. Default here: 50.
- `page` (integer): Page number, 1-based. Default 1.

### `lacrm_get_contact_groups` (~102 tokens)

Get a contact's groups

List the groups one contact or company belongs to. LACRM: GetGroupsAttachedToContact.

Input parameters:

- `contact_id` (string, required): The contact or company id (a long numeric Uid — always pass it as a string).
- `max_results` (integer): Results per page (MaxNumberOfResults), 1-10000. Default here: 50.
- `page` (integer): Page number, 1-based. Default 1.

### `lacrm_list_custom_fields` (~157 tokens)

List custom fields

List the account's field definitions (name, type, options) for contacts, companies or pipelines — use the Name values as keys in custom_fields when creating/editing contacts. LACRM: GetCustomFields.

Input parameters:

- `include_archived` (boolean): Include deleted fields. Default false.
- `max_results` (integer): Results per page (MaxNumberOfResults), 1-10000. Default here: 50.
- `page` (integer): Page number, 1-based. Default 1.
- `pipeline_id` (string): For pipeline fields, only this pipeline's (a long numeric Uid — always pass it as a string).
- `record_type` (string): Only fields for this record type.

### `lacrm_create_contact` (~306 tokens)

Create a contact or company

Create a new contact (person) or company record. For a person, company_name links them to that company (creating it if needed). Company names must be unique. If assigned_to is omitted, the record is assigned to the API key's own user (one extra GetUser call). Returns { ContactId }. LACRM: CreateContact.

Input parameters:

- `address` (array): Address(es).
- `assigned_to`: UserId to assign the record to. Default: the API key's user.
- `background_info` (string): The Background Info text.
- `birthday` (string): Birthday, yyyy-mm-dd (or 0000-M-D for no year).
- `company_name` (string): For a PERSON: the company they work at (created if it does not exist). Not used for company records.
- `custom_fields` (object): Extra fields keyed by the account's field names exactly as LACRM shows them (e.g. {"Lead Source": "Referral"}). Use lacrm_list_custom_fields to find them. Merged verbatim into Parameters.
- `email` (array): Email address(es).
- `is_company` (boolean): true to create a COMPANY record. Default false (a person).
- `job_title` (string): Job title (people only).
- `name` (string, required): Full name of the person, or the company's name.
- `phone` (array): Phone number(s).
- `website` (array): Website URL(s).

### `lacrm_edit_contact` (~320 tokens)

Edit a contact or company

Update fields on an existing contact or company. Only the fields you pass change; omitted fields are left alone. Multi-value fields (email, phone, address, website) are REPLACED by the list you pass. Set is_company=true when renaming a company. LACRM: EditContact.

Input parameters:

- `address` (array): Address(es).
- `assigned_to`: Reassign to this UserId.
- `background_info` (string): The Background Info text.
- `birthday` (string): Birthday, yyyy-mm-dd (or 0000-M-D for no year).
- `company_name` (string): For a PERSON: the company they work at (created if it does not exist). Not used for company records.
- `contact_id` (string, required): The contact or company id (a long numeric Uid — always pass it as a string).
- `custom_fields` (object): Extra fields keyed by the account's field names exactly as LACRM shows them (e.g. {"Lead Source": "Referral"}). Use lacrm_list_custom_fields to find them. Merged verbatim into Parameters.
- `email` (array): Email address(es).
- `is_company` (boolean): Set true if this record is a company, so `name` maps to its Company Name field.
- `job_title` (string): Job title (people only).
- `name` (string): New full name (person) or company name.
- `phone` (array): Phone number(s).
- `website` (array): Website URL(s).

### `lacrm_create_note` (~106 tokens)

Add a note to a contact

Attach a plain-text note to a contact or company's history (newlines kept, HTML/markdown escaped). Returns { NoteId }. LACRM: CreateNote.

Input parameters:

- `contact_id` (string, required): The contact or company id (a long numeric Uid — always pass it as a string).
- `date_displayed` (string): When the note should appear in history, ISO 8601 date-time. Default: now.
- `note` (string, required): The note text.

### `lacrm_create_task` (~167 tokens)

Create a task

Create a to-do on a user's task list (date only, no time — use lacrm_create_event for timed things). Optionally attach it to a contact. Returns { TaskId }. LACRM: CreateTask.

Input parameters:

- `assigned_to`: UserId to assign to. Default: you.
- `calendar_id` (string): Calendar to file it under. Default: your primary (a long numeric Uid — always pass it as a string).
- `contact_id` (string): Attach the task to this contact or company (a long numeric Uid — always pass it as a string).
- `description` (string): Longer details.
- `due_date` (string): Due date, yyyy-mm-dd.
- `name` (string, required): Task name shown on the task list.

### `lacrm_edit_task` (~175 tokens)

Edit or complete a task

Update a task — including marking it complete (is_complete=true) or re-opening it (false). Only passed fields change. LACRM: EditTask.

Input parameters:

- `assigned_to`: Reassign to this UserId.
- `calendar_id` (string): Move to this calendar (a long numeric Uid — always pass it as a string).
- `contact_id` (string): Attach to this contact instead (a long numeric Uid — always pass it as a string).
- `description` (string)
- `due_date` (string): New due date, yyyy-mm-dd.
- `is_complete` (boolean): true = mark complete, false = mark incomplete.
- `name` (string)
- `task_id` (string, required): The task id (a long numeric Uid — always pass it as a string).

### `lacrm_create_event` (~196 tokens)

Schedule a calendar event

Create a timed (or all-day) event on your calendar, optionally with contacts/users as attendees. The timezone of start_date becomes the event's timezone. Returns { EventId }. LACRM: CreateEvent.

Input parameters:

- `attendees` (array): Attendees: contacts and/or users.
- `calendar_id` (string): Calendar to put it on. Default: your primary (a long numeric Uid — always pass it as a string).
- `description` (string)
- `end_date` (string, required): End, ISO 8601 date-time.
- `is_all_day` (boolean): All-day event (times ignored). Default false.
- `location` (string)
- `name` (string, required): Event name shown on the calendar.
- `start_date` (string, required): Start, ISO 8601 date-time, e.g. 2026-10-06T14:00:00-05:00.

### `lacrm_create_pipeline_item` (~172 tokens)

Add a contact to a pipeline

Create a pipeline item (deal, lead...) on a contact in a given pipeline and status, with an optional note. Returns { PipelineItemId }. LACRM: CreatePipelineItem.

Input parameters:

- `contact_id` (string, required): The contact or company id (a long numeric Uid — always pass it as a string).
- `note` (string): Optional note shown in the item's history.
- `pipeline_id` (string, required): The pipeline id (from lacrm_list_pipelines) (a long numeric Uid — always pass it as a string).
- `run_status_automation` (boolean): Run the status's automation. Default false.
- `status_id` (string, required): The starting status id (from the pipeline's Statuses) (a long numeric Uid — always pass it as a string).

### `lacrm_update_pipeline_item` (~129 tokens)

Move or annotate a pipeline item

Move a pipeline item to another status (e.g. Prospect → Won) and/or add a note to its history. LACRM: EditPipelineItem.

Input parameters:

- `note` (string): Note to add to the item's history.
- `pipeline_item_id` (string, required): The pipeline item id (a long numeric Uid — always pass it as a string).
- `run_status_automation` (boolean): If the status changes, run its automation. Default false.
- `status_id` (string): The new status id (a long numeric Uid — always pass it as a string).

### `lacrm_add_contact_to_group` (~119 tokens)

Add a contact to a group

Add a contact or company to a group (creates a group membership). Identify the group by group_id (preferred) or group_name — not both. LACRM: CreateGroupMembership.

Input parameters:

- `contact_id` (string, required): The contact or company id (a long numeric Uid — always pass it as a string).
- `group_id` (string): The group id (a long numeric Uid — always pass it as a string).
- `group_name` (string): The group name, if you do not have its id.

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/io-usefulapi-less-annoying-crm/less-annoying-crm#diagnostics

## Score history

- 2026-10-04: 76
- 2026-10-03: 75
- 2026-10-02: 75
- 2026-10-01: 18
- 2026-09-30: 18
- 2026-09-29: 18

## Common questions

### What is the io.usefulapi/less-annoying-crm MCP server?

io.usefulapi/less-annoying-crm is an MCP server listed in the public MCP registry as io.usefulapi/less-annoying-crm. Read and write Less Annoying CRM contacts, notes, tasks, events, pipelines and groups. This page covers its hosted endpoint (https://less-annoying-crm.usefulapi.io/mcp).

### Is the io.usefulapi/less-annoying-crm MCP server safe to use?

io.usefulapi/less-annoying-crm scores 76 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the io.usefulapi/less-annoying-crm MCP server expose?

io.usefulapi/less-annoying-crm exposes 23 tools: lacrm_get_user, lacrm_list_users, lacrm_search_contacts, lacrm_get_contact, lacrm_list_notes, and 18 more. Their descriptions and schemas cost roughly 3,568 tokens of context every time the server is loaded.

### Does the io.usefulapi/less-annoying-crm MCP server require authentication?

Yes. io.usefulapi/less-annoying-crm asked us for credentials when we connected, so you will need to authorise it in your MCP client before it can do anything.

### Is the io.usefulapi/less-annoying-crm MCP server still maintained?

io.usefulapi/less-annoying-crm is still listed as active in the MCP registry. We last reached this channel on 4 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

## Links

- Remote endpoint: https://less-annoying-crm.usefulapi.io/mcp
- Repository: https://github.com/m190/usefulapi-mcp
- Changelog RSS feed: https://verifymcp.io/servers/io-usefulapi-less-annoying-crm/less-annoying-crm.xml
- Changelog JSON feed: https://verifymcp.io/servers/io-usefulapi-less-annoying-crm/less-annoying-crm.json
- HTML version of this page: https://verifymcp.io/servers/io-usefulapi-less-annoying-crm/less-annoying-crm
