# io.github.Mad-Man-Dan/karbon-mcp-server (npm · karbon-mcp-server)

Unofficial MCP server for Karbon practice management: contacts, work, time, invoices, payments.

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

## Components

- npm · `karbon-mcp-server`: 78/100 (this document), [markdown](https://verifymcp.io/servers/mad-man-dan-karbon-mcp-server/karbon-mcp-server.md), [page](https://verifymcp.io/servers/mad-man-dan-karbon-mcp-server/karbon-mcp-server)

## Channel facts

- Registry: `npm`
- Package: `karbon-mcp-server`
- Version: `0.2.4`
- 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**: 87/100
  - No malware found by supply-chain analysis.
  - Only part of the dependency tree could be resolved (95 of 99), so this covers what we could see, not the whole tree.
  - No install/post-install scripts declared.
  - Only part of the dependency tree could be resolved (95 of 99), 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 Mad-Man-Dan/karbon-mcp-server).
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 17 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 71/100
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 5478 tokens (~109/item across 50 items; 50 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 88/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 64% 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 mad-man-dan-karbon-mcp-server -- npx -y karbon-mcp-server
```

### Codex

```bash
codex mcp add mad-man-dan-karbon-mcp-server -- npx -y karbon-mcp-server
```

### opencode

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

### OpenClaw

```bash
openclaw mcp add mad-man-dan-karbon-mcp-server --command npx --arg -y --arg karbon-mcp-server
```

### Hermes

```yaml
mcp_servers:
  mad-man-dan-karbon-mcp-server:
    command: "npx"
    args: ["-y", "karbon-mcp-server"]
```

### Other

```json
{
  "mcpServers": {
    "mad-man-dan-karbon-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "karbon-mcp-server"
      ]
    }
  }
}
```

## 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 78, +1)

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

### 2026-08-02 (score 77, +72)

- [security improvement] Known CVEs: unverified → partial
- [security improvement] Install scripts: unverified → pass
- [security improvement] Provenance: unverified → pass
- [security improvement] Malware scan: unverified → pass
- [security] Stability: Stability not yet verified: not enough scan history yet (needs a 30-day window).
- [security] The attested source repository moved: Mad-Man-Dan/karbon-mcp-server
- [functional improvement] Stability: unverified → 0.23
- [functional improvement] Maintenance: unverified → pass
- [functional improvement] Dependency health: unverified → partial
- [functional improvement] License: unverified → pass
- [functional improvement] MCP protocol: unverified → pass
- [functional improvement] Tool coverage: unverified → 100
- [functional] Licence: MIT

### 2026-08-01 (score 5, −28)

- [security] Stability: Stability not yet verified: we do not have a sandbox capture of the MCP schema this version of the package serves yet.
- [functional regression] Capabilities: pass → unverified
- [functional regression] Tool coverage: 100 → unverified

### 2026-07-31 (score 33, +5)

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

### 2026-07-30 (score 28, −61)

- [security regression] Malware scan: pass → unverified
- [security regression] Known CVEs: partial → unverified
- [functional regression] Tool coverage: 100 → unverified
- [functional regression] Dependency health: partial → unverified
- [functional] First check of Schema quality: unverified

### 2026-07-29 (score 89, +45)

- [security improvement] Known CVEs: unverified → partial
- [security improvement] Provenance: unverified → pass
- [security improvement] Install scripts: unverified → pass
- [security] The attested source repository moved: Mad-Man-Dan/karbon-mcp-server
- [functional improvement] License: unverified → pass
- [functional improvement] Schema quality: unverified → good
- [functional improvement] Maintenance: unverified → pass
- [functional improvement] Dependency health: unverified → partial
- [functional] Licence: MIT

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

First indexed and scored.

## MCP tools (50)

### `list_contacts` (~153 tokens)

List contacts

List or search person contacts in Karbon. Supports OData filtering, e.g. filter: "contains(FullName,'Smith')" or "ContactType eq 'Client'".

Input parameters:

- `filter` (string): OData $filter expression, e.g. "contains(FullName,'Smith')" or "PrimaryStatus eq 'InProgress'". Operators: eq, ne, gt, ge, lt, le, and, or, contains().
- `orderby` (string): OData $orderby, e.g. "LastModifiedDateTime desc"
- `skip` (integer): Number of results to skip, for pagination
- `top` (integer): Max results to return (1-100, default 100)

### `get_contact` (~107 tokens)

Get contact

Get a single person contact by ContactKey — or by your own UserDefinedIdentifier — optionally expanding related data (BusinessCards, AccountingDetail, ClientTeam). Provide exactly one of contactKey or userDefinedIdentifier.

Input parameters:

- `contactKey` (string): The Karbon ContactKey
- `expand` (string): Comma-separated related data to include: BusinessCards, AccountingDetail, ClientTeam
- `userDefinedIdentifier` (string): Look up by your own external ID instead of the ContactKey

### `create_contact` (~147 tokens)

Create contact

Create a new person contact in Karbon.

Input parameters:

- `BusinessCards` (array)
- `ClientManager` (string)
- `ClientOwner` (string): Email address of the Karbon user who owns this client
- `ContactType` (string): Contact type label, e.g. 'Client', 'Prospect'. Valid values come from get_tenant_settings.
- `FirstName` (string, required)
- `LastName` (string, required)
- `MiddleName` (string)
- `PreferredName` (string)
- `RestrictionLevel` (string)
- `Salutation` (string)
- `UserDefinedIdentifier` (string): Your own external ID for this contact

### `update_contact` (~127 tokens)

Update contact

Update fields on an existing person contact (partial update via PATCH). Only include the fields you want to change.

Input parameters:

- `ClientManager` (string)
- `ClientOwner` (string)
- `ContactType` (string)
- `FirstName` (string)
- `LastName` (string)
- `MiddleName` (string)
- `PreferredName` (string)
- `RestrictionLevel` (string)
- `Salutation` (string)
- `UserDefinedIdentifier` (string)
- `contactKey` (string, required): The Karbon ContactKey to update

### `list_organizations` (~147 tokens)

List organizations

List or search organization contacts in Karbon. Supports OData filtering, e.g. filter: "contains(FullName,'Acme')".

Input parameters:

- `filter` (string): OData $filter expression, e.g. "contains(FullName,'Smith')" or "PrimaryStatus eq 'InProgress'". Operators: eq, ne, gt, ge, lt, le, and, or, contains().
- `orderby` (string): OData $orderby, e.g. "LastModifiedDateTime desc"
- `skip` (integer): Number of results to skip, for pagination
- `top` (integer): Max results to return (1-100, default 100)

### `get_organization` (~111 tokens)

Get organization

Get a single organization by OrganizationKey — or by your own UserDefinedIdentifier — optionally expanding related data (BusinessCards, AccountingDetail, ClientTeam, Contacts). Provide exactly one of organizationKey or userDefinedIdentifier.

Input parameters:

- `expand` (string): Comma-separated related data to include: BusinessCards, AccountingDetail, ClientTeam, Contacts
- `organizationKey` (string): The Karbon OrganizationKey
- `userDefinedIdentifier` (string): Look up by your own external ID instead of the OrganizationKey

### `create_organization` (~111 tokens)

Create organization

Create a new organization contact in Karbon.

Input parameters:

- `ClientManager` (string)
- `ClientOwner` (string): Email address of the Karbon user who owns this client
- `ContactType` (string): Contact type label, e.g. 'Client', 'Prospect'. Valid values come from get_tenant_settings.
- `FullName` (string, required): The organization's name
- `RestrictionLevel` (string)
- `UserDefinedIdentifier` (string): Your own external ID for this organization

### `update_organization` (~95 tokens)

Update organization

Update fields on an existing organization (partial update via PATCH). Only include the fields you want to change.

Input parameters:

- `ClientManager` (string)
- `ClientOwner` (string)
- `ContactType` (string)
- `FullName` (string)
- `RestrictionLevel` (string)
- `UserDefinedIdentifier` (string)
- `organizationKey` (string, required): The Karbon OrganizationKey to update

### `list_client_groups` (~157 tokens)

List client groups

List or search client groups in Karbon. Supports OData filtering, e.g. filter: "contains(FullName,'Smith Family')" or "UserDefinedIdentifier eq 'ABC123'".

Input parameters:

- `filter` (string): OData $filter expression, e.g. "contains(FullName,'Smith')" or "PrimaryStatus eq 'InProgress'". Operators: eq, ne, gt, ge, lt, le, and, or, contains().
- `orderby` (string): OData $orderby, e.g. "LastModifiedDateTime desc"
- `skip` (integer): Number of results to skip, for pagination
- `top` (integer): Max results to return (1-100, default 100)

### `get_client_group` (~116 tokens)

Get client group

Get a single client group by ClientGroupKey — or by your own UserDefinedIdentifier — optionally expanding related data (BusinessCard, ClientTeam). Includes the group's members (contacts and organizations). Provide exactly one of clientGroupKey or userDefinedIdentifier.

Input parameters:

- `clientGroupKey` (string): The Karbon ClientGroupKey
- `expand` (string): Comma-separated related data to include: BusinessCard, ClientTeam
- `userDefinedIdentifier` (string): Look up by your own external ID instead of the ClientGroupKey

### `create_client_group` (~158 tokens)

Create client group

Create a new client group in Karbon. Members are existing contacts and/or organizations.

Input parameters:

- `ClientManager` (string)
- `ClientOwner` (string): Email address of the Karbon user who owns this client relationship
- `ContactType` (string): Contact type label, e.g. 'Client'. Valid values come from get_tenant_settings.
- `EntityDescription` (object): Free-form description of the client group
- `FullName` (string, required): The full name of the client group
- `Members` (array)
- `PrimaryContact` (string): ContactKey of the group's main contact
- `RestrictionLevel` (string)
- `UserDefinedIdentifier` (string): Your own external ID for this client group

### `update_client_group` (~114 tokens)

Update client group

Update fields on an existing client group (partial update via PATCH). Only include the fields you want to change.

Input parameters:

- `ClientManager` (string)
- `ClientOwner` (string)
- `ContactType` (string)
- `EntityDescription` (object)
- `FullName` (string)
- `PrimaryContact` (string)
- `RestrictionLevel` (string)
- `UserDefinedIdentifier` (string)
- `clientGroupKey` (string, required): The Karbon ClientGroupKey to update

### `list_work_items` (~186 tokens)

List work items

List or search work items (jobs/engagements) in Karbon. Useful filters: "PrimaryStatus eq 'InProgress'", "AssigneeEmailAddress eq 'user@firm.com'", "DueDate lt 2026-08-01". PrimaryStatus values: Planned, ReadyToStart, InProgress, Waiting, Completed.

Input parameters:

- `filter` (string): OData $filter expression, e.g. "contains(FullName,'Smith')" or "PrimaryStatus eq 'InProgress'". Operators: eq, ne, gt, ge, lt, le, and, or, contains().
- `orderby` (string): OData $orderby, e.g. "LastModifiedDateTime desc"
- `skip` (integer): Number of results to skip, for pagination
- `top` (integer): Max results to return (1-100, default 100)

### `get_work_item` (~34 tokens)

Get work item

Get a single work item by WorkItemKey.

Input parameters:

- `workItemKey` (string, required): The Karbon WorkItemKey

### `get_estimate_summary` (~67 tokens)

Get estimate summary

Get the estimate summary for a work item (read-only): budgeted vs. actual time and value. Useful for 'are we over budget on this job' questions — pair with list_time_entries for detail.

Input parameters:

- `workItemKey` (string, required): The Karbon WorkItemKey

### `create_work_item` (~229 tokens)

Create work item

Create a new work item in Karbon. WorkType and status values are tenant-specific — call get_tenant_settings first if unsure.

Input parameters:

- `AssigneeEmailAddress` (string, required): Email address of the Karbon user assigned to this work
- `ClientKey` (string, required): Key of the client this work is for (ContactKey, OrganizationKey, or ClientGroupKey)
- `ClientType` (string, required)
- `DeadlineDate` (string)
- `Description` (string)
- `DueDate` (string): ISO 8601 date or date-time
- `EstimatedBudget` (number)
- `PrimaryStatus` (string)
- `SecondaryStatus` (string): Tenant-specific status label from get_tenant_settings
- `StartDate` (string, required): ISO 8601 date or date-time, e.g. 2026-08-01
- `Title` (string, required)
- `WorkTemplateKey` (string): Create from a work template (see list_work_templates)
- `WorkType` (string): Tenant-specific work type label, e.g. 'Tax Return'

### `update_work_item` (~120 tokens)

Update work item

Update fields on an existing work item (partial update via PATCH). Only include the fields you want to change.

Input parameters:

- `AssigneeEmailAddress` (string): Must be an existing Karbon user's email
- `DeadlineDate` (string)
- `Description` (string)
- `DueDate` (string)
- `StartDate` (string): ISO 8601 date or date-time
- `Title` (string)
- `WorkType` (string)
- `workItemKey` (string, required): The Karbon WorkItemKey to update

### `get_note` (~30 tokens)

Get note

Get a single note by its NoteID.

Input parameters:

- `noteId` (string, required): The Karbon NoteID

### `get_comment` (~41 tokens)

Get comment

Get a single comment by its CommentKey. Comments appear on work item and client timelines alongside notes.

Input parameters:

- `commentKey` (string, required): The Karbon CommentKey

### `create_note` (~146 tokens)

Create note

Create a note in Karbon, optionally linked to work items, contacts, organizations, or client groups via timelines. Notes linked to a work item also appear on the client's timeline.

Input parameters:

- `AssigneeEmailAddress` (string): Assign the note as a to-do for this Karbon user
- `AuthorEmailAddress` (string, required): Email address of the Karbon user authoring the note
- `Body` (string, required): Note body (supports basic HTML)
- `DueDate` (string): ISO 8601 date
- `Subject` (string, required)
- `Timelines` (array): Entities to link this note to
- `TodoDate` (string): ISO 8601 date

### `list_timesheets` (~147 tokens)

List timesheets

List timesheets (read-only). Useful filters: "StartDate ge 2026-07-01", "UserKey eq '...'".

Input parameters:

- `filter` (string): OData $filter expression, e.g. "contains(FullName,'Smith')" or "PrimaryStatus eq 'InProgress'". Operators: eq, ne, gt, ge, lt, le, and, or, contains().
- `orderby` (string): OData $orderby, e.g. "LastModifiedDateTime desc"
- `skip` (integer): Number of results to skip, for pagination
- `top` (integer): Max results to return (1-100, default 100)

### `get_timesheet` (~52 tokens)

Get timesheet

Get a single timesheet by TimesheetKey, optionally expanding TimeEntries.

Input parameters:

- `expandTimeEntries` (boolean): Include individual time entries
- `timesheetKey` (string, required): The Karbon TimesheetKey

### `list_time_entries` (~138 tokens)

List time entries

List individual time entries (read-only). Useful for reporting on time logged against clients or work items.

Input parameters:

- `filter` (string): OData $filter expression, e.g. "contains(FullName,'Smith')" or "PrimaryStatus eq 'InProgress'". Operators: eq, ne, gt, ge, lt, le, and, or, contains().
- `orderby` (string): OData $orderby, e.g. "LastModifiedDateTime desc"
- `skip` (integer): Number of results to skip, for pagination
- `top` (integer): Max results to return (1-100, default 100)

### `get_time_entry` (~41 tokens)

Get time entry

Get a single individual time entry by its IndividualTimeEntryKey (read-only).

Input parameters:

- `timeEntryKey` (string, required): The Karbon IndividualTimeEntryKey

### `list_invoices` (~172 tokens)

List invoices

List invoices in Karbon (read-only). Supports OData filtering, e.g. filter: "InvoiceStatus eq 'AwaitingPayment'" or "TotalAmountDue gt 0". Statuses: Approved, AwaitingPayment, Paid, Exported, Voided.

Input parameters:

- `filter` (string): OData $filter expression, e.g. "contains(FullName,'Smith')" or "PrimaryStatus eq 'InProgress'". Operators: eq, ne, gt, ge, lt, le, and, or, contains().
- `orderby` (string): OData $orderby, e.g. "LastModifiedDateTime desc"
- `skip` (integer): Number of results to skip, for pagination
- `top` (integer): Max results to return (1-100, default 100)

### `get_invoice` (~65 tokens)

Get invoice

Get a single invoice by InvoiceKey (read-only), optionally expanding related data (LineItems, Payments, Data).

Input parameters:

- `expand` (string): Comma-separated related data to include: LineItems, Payments, Data
- `invoiceKey` (string, required): The Karbon InvoiceKey

### `list_payments` (~65 tokens)

List payments

List payments recorded against invoices in Karbon (read-only). Supports pagination only — the Payments endpoint does not accept OData filters.

Input parameters:

- `skip` (integer): Number of results to skip, for pagination
- `top` (integer): Max results to return (1-100)

### `get_payment` (~32 tokens)

Get payment

Get a single payment by PaymentKey (read-only).

Input parameters:

- `paymentKey` (string, required): The Karbon PaymentKey

### `list_teams` (~61 tokens)

List teams

List teams in Karbon (read-only). Supports OData filtering, e.g. filter: "contains(Name,'Tax')".

Input parameters:

- `filter` (string): OData $filter expression
- `skip` (integer)
- `top` (integer)

### `get_team` (~39 tokens)

Get team

Get a single team by TeamKey, including its members (users and sub-teams).

Input parameters:

- `teamKey` (string, required): The Karbon TeamKey

### `add_team_members` (~81 tokens)

Add team members

Add one or more users to a team by their UserKeys (find them with list_users). Users already on the team are skipped. Team membership can affect work visibility and assignment — confirm with the user before changing it.

Input parameters:

- `UserKeys` (array, required): UserKeys of the users to add
- `teamKey` (string, required): The Karbon TeamKey

### `remove_team_member` (~65 tokens)

Remove team member

Remove a user from a team by their UserKey. Team membership can affect work visibility and assignment — confirm with the user before changing it.

Input parameters:

- `UserKey` (string, required): UserKey of the user to remove
- `teamKey` (string, required): The Karbon TeamKey

### `list_entity_files` (~77 tokens)

List files on an entity

List the files attached to a work item, contact, or organization — name, size, mime type, created date, and a DownloadUrl usable with download_file. Download links expire 15 minutes after this call.

Input parameters:

- `entityKey` (string, required): The key of the entity to list files for
- `entityType` (string, required)

### `download_file` (~117 tokens)

Download a file

Download a Karbon file to a local path on the machine running this MCP server. Get the DownloadUrl from list_entity_files first — download links expire after 15 minutes, so re-list if the download fails with an auth error. Ask the user where to save before writing outside a temp directory, and never overwrite a file the user didn't ask you to replace.

Input parameters:

- `downloadUrl` (string, required): The DownloadUrl returned by list_entity_files
- `savePath` (string, required): Absolute local file path to save to, including the file name

### `upload_file` (~297 tokens)

Upload a file

Upload a file to Karbon and attach it to a work item, contact, organization, or client group (at least one key is required). SIZE LIMITS: keep uploads small — Karbon rejects oversized uploads, and this server reads the whole file into memory. Prefer filePath (a path on the machine running this MCP server) whenever possible; only use contentBase64 for small files (roughly under 1 MB), because base64 inflates data ~33% and large payloads can exceed the AI client's message limits or be truncated mid-transfer. If a file seems large (tens of MB or more), tell the user to upload it through Karbon's own UI instead. SECURITY: only upload files the user explicitly pointed you to. Never upload configuration files, credential stores, environment files, keys, or anything the user has not named — uploading puts the file's contents in the Karbon tenant.

Input parameters:

- `clientGroupKey` (string)
- `contactKey` (string)
- `contentBase64` (string): Base64-encoded file content — small files only; requires fileName
- `fileName` (string): File name including extension. Required with contentBase64; defaults to the filePath basename otherwise.
- `filePath` (string): Absolute path of the file on the machine running this MCP server (preferred)
- `organizationKey` (string)
- `workItemKey` (string)

### `get_work_schedule` (~43 tokens)

Get work schedule

Get a recurring work schedule by WorkScheduleKey — the recurrence rules that automatically generate work items.

Input parameters:

- `workScheduleKey` (string, required): The Karbon WorkScheduleKey

### `create_work_schedule` (~365 tokens)

Create work schedule

Create a recurring work schedule from an existing work item. The schedule will automatically generate new work items on the recurrence you set — confirm the recurrence details with the user before calling. Note: RecurrenceFrequency cannot be changed after creation.

Input parameters:

- `AssigneeUserKey` (string): UserKey to assign generated work items to
- `CreatedFromWorkItemKey` (string, required): The WorkItemKey the schedule is created from
- `CustomFrequencyMultiple` (integer, required): Multiple of the frequency unit; use 1 unless RecurrenceFrequency is Custom
- `CustomFrequencyUnits` (string): Only when RecurrenceFrequency is Custom
- `InitializeBeforeStartDateMultiple` (integer)
- `InitializeBeforeStartDateUnits` (string): Create the work item this long before its start date
- `InitializeTasksBeforeStartDateMultiple` (integer, required)
- `InitializeTasksBeforeStartDateUnits` (string, required): Create the work item's tasks/budget this long before its start date
- `PreventStartEndOnWeekend` (boolean, required): If true, generated work items never start on a weekend
- `RecurrenceFrequency` (string, required)
- `ScheduleDueDateDays` (integer): The day count for the due date method (not used with LastDayOfMonth/NoDueDate)
- `ScheduleDueDateMethod` (string, required)
- `ScheduleDueDateMonthMultiple` (integer): Only with DayOfSubsequentMonth: how many months later
- `ScheduleEndDate` (string): ISO 8601 date the schedule stops; omit to run forever
- `ScheduleStartDate` (string, required): ISO 8601 date the schedule starts
- `WorkItemTitleDefinition` (string, required): Title format for generated work items; supports Karbon title tokens (e.g. period/date placeholders)

### `update_work_schedule` (~118 tokens)

Update work schedule

Update a work schedule (partial via PATCH). The API only supports changing the end date and the assignee here. Note: changing AssigneeUserKey reassigns every not-yet-started work item the schedule has generated — confirm with the user first.

Input parameters:

- `AssigneeUserKey` (string)
- `ScheduleEndDate` (string|null): ISO 8601 date to stop the schedule; pass null to clear the end date (run forever)
- `workScheduleKey` (string, required): The Karbon WorkScheduleKey to update

### `get_business_card` (~78 tokens)

Get business card

Get a single business card by BusinessCardKey. Business cards hold the contact details (email, phone, address, websites) of a contact, organization, or client group. Find the key by expanding BusinessCards on get_contact / get_organization / get_client_group.

Input parameters:

- `businessCardKey` (string, required): The Karbon BusinessCardKey

### `update_business_card` (~226 tokens)

Update business card

Update a business card (full replace via PUT) — this is how you change a contact's, organization's, or client group's email addresses, phone numbers, and addresses. Fetch the card first with get_business_card and send back the complete card with your changes, since omitted fields are cleared.

Input parameters:

- `Addresses` (array)
- `EmailAddresses` (array)
- `EntityKey` (string, required): The key of the contact, organization, or client group this card belongs to
- `EntityType` (string, required): The type of entity this business card belongs to
- `FacebookLink` (string)
- `IsPrimaryCard` (boolean)
- `LinkedInLink` (string)
- `OrganizationKey` (string): For a contact's card: the organization the contact works at
- `PhoneNumbers` (array)
- `RoleOrTitle` (string)
- `SkypeLink` (string)
- `TwitterLink` (string)
- `WebSites` (array)
- `businessCardKey` (string, required): The Karbon BusinessCardKey to update

### `list_custom_fields` (~54 tokens)

List custom field definitions

List all custom field definitions for the Karbon tenant — field names, types (Text, Number, Date, Boolean, Colleague, ListSingleSelect, ListMultipleSelect), list options, and which entities they apply to.

### `get_custom_field_values` (~53 tokens)

Get custom field values

Get the custom field values set on a specific entity (contact, organization, or client group) by its entity key.

Input parameters:

- `entityKey` (string, required): The ContactKey, OrganizationKey, or ClientGroupKey

### `set_custom_field_values` (~97 tokens)

Set custom field values

Set custom field values on an entity (contact, organization, or client group). Use list_custom_fields for the available definitions and get_custom_field_values to see what's currently set. Values are always passed as an array of strings, even for single values.

Input parameters:

- `CustomFieldValues` (array, required): The custom field values to set on the entity
- `entityKey` (string, required): The ContactKey, OrganizationKey, or ClientGroupKey

### `create_custom_field` (~108 tokens)

Create custom field definition

Create a new custom field definition for the whole Karbon tenant. This changes the firm's shared configuration, not just one record — state the field name, type, and visibility to the user and get their explicit confirmation before calling.

Input parameters:

- `IsVisibleToContacts` (boolean)
- `IsVisibleToOrganizations` (boolean)
- `ListOptions` (array): Options for list-type fields
- `Name` (string, required): The field name shown in Karbon
- `Type` (string, required)

### `delete_custom_field` (~101 tokens)

Delete custom field definition

DESTRUCTIVE AND IRREVERSIBLE: deleting a custom field definition permanently removes the field AND every value stored in it across all contacts, organizations, and client groups in the tenant. Never call this without first telling the user exactly which field will be deleted (by name, via list_custom_fields) and receiving their explicit confirmation for that specific field.

Input parameters:

- `customFieldDefinitionKey` (string, required): The CustomFieldDefinitionKey to delete (from list_custom_fields)

### `list_users` (~129 tokens)

List users

List Karbon users (team members) on this account.

Input parameters:

- `filter` (string): OData $filter expression, e.g. "contains(FullName,'Smith')" or "PrimaryStatus eq 'InProgress'". Operators: eq, ne, gt, ge, lt, le, and, or, contains().
- `orderby` (string): OData $orderby, e.g. "LastModifiedDateTime desc"
- `skip` (integer): Number of results to skip, for pagination
- `top` (integer): Max results to return (1-100, default 100)

### `get_user` (~32 tokens)

Get user

Get a single Karbon user by their UserId.

Input parameters:

- `userId` (string, required): The Karbon UserId

### `get_tenant_settings` (~47 tokens)

Get tenant settings

Get this Karbon account's configuration: valid work statuses (secondary statuses), work types, and contact types. Call this before creating or updating work items or contacts with tenant-specific values.

### `list_work_templates` (~141 tokens)

List work templates

List work templates available on this account. Use a WorkTemplateKey with create_work_item to create templated work.

Input parameters:

- `filter` (string): OData $filter expression, e.g. "contains(FullName,'Smith')" or "PrimaryStatus eq 'InProgress'". Operators: eq, ne, gt, ge, lt, le, and, or, contains().
- `orderby` (string): OData $orderby, e.g. "LastModifiedDateTime desc"
- `skip` (integer): Number of results to skip, for pagination
- `top` (integer): Max results to return (1-100, default 100)

### `get_work_template` (~41 tokens)

Get work template

Get a single work template by WorkTemplateKey, including its task and section structure.

Input parameters:

- `workTemplateKey` (string, required): The Karbon WorkTemplateKey

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/mad-man-dan-karbon-mcp-server/karbon-mcp-server#diagnostics

## Score history

- 2026-08-03: 78
- 2026-08-02: 77
- 2026-08-01: 5
- 2026-07-31: 33
- 2026-07-30: 28
- 2026-07-29: 89
- 2026-07-28: 44
- 2026-07-27: 44

## Links

- npm package: https://www.npmjs.com/package/karbon-mcp-server
- Socket report: https://socket.dev/npm/package/karbon-mcp-server
- Repository: https://github.com/Mad-Man-Dan/karbon-mcp-server
- Changelog RSS feed: https://verifymcp.io/servers/mad-man-dan-karbon-mcp-server/karbon-mcp-server/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/mad-man-dan-karbon-mcp-server/karbon-mcp-server/changelog.json
- HTML version of this page: https://verifymcp.io/servers/mad-man-dan-karbon-mcp-server/karbon-mcp-server
