npm package: @neutralthiscrazy/twenty-crm-mcp-server
Description: MCP server for Twenty CRM workspaces with records, metadata, schema, and workflow tools
Author: neutralthiscrazy
Latest version: 0.1.1

# twenty-crm-mcp-server

[![npm version](https://img.shields.io/npm/v/%40neutralthiscrazy%2Ftwenty-crm-mcp-server)](https://www.npmjs.com/package/@neutralthiscrazy/twenty-crm-mcp-server)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

Model Context Protocol (MCP) server for [Twenty CRM](https://twenty.com) workspaces.

It provides a practical admin and operations layer for:

- records CRUD across any object,
- metadata object and field management,
- schema-as-code export, diff, and apply,
- workflow read, validation, create, update, activate, and deactivate.

## Why this project

Many Twenty integrations expose basic CRUD but stop short of safe metadata and workflow administration. `twenty-crm-mcp-server` is built to support real operational work from AI tools: evolving schema, linking relations, and managing workflow definitions with consistent error handling.

## Features

- Generic records tools for all objects (`records_*`)
- Metadata tools for custom objects/fields/relations (`meta_*`)
- Batch tools (`records_upsert_batch`, `meta_create_fields_batch`)
- Schema-as-code tools (`schema_export`, `schema_diff`, `schema_apply`)
- Workflow tools (`workflow_*`) with definition validation and sync helpers
- Metadata mutation safety guardrails (mutex + cooldown + readiness polling)
- Auto-retry for transient API failures (`429/502/503/504`)
- Normalized error contract across tools
- Auto-renewed user session auth (email/password)
- Optional fallback to API key

## Requirements

- Node.js 18+
- Twenty workspace base URL (self-hosted or cloud)
- One auth mode:
  - recommended: user session (`TWENTY_AUTH_EMAIL` + `TWENTY_AUTH_PASSWORD`)
  - optional: API key (`TWENTY_API_KEY`)

## Install

Global install:

```bash
npm i -g @neutralthiscrazy/twenty-crm-mcp-server
```

Or use directly with `npx`:

```bash
npx -y @neutralthiscrazy/twenty-crm-mcp-server
```

## Authentication modes

Auth priority order:

1. auto user session (`TWENTY_AUTH_EMAIL` + `TWENTY_AUTH_PASSWORD`)
2. API key (`TWENTY_API_KEY`)

## Service account recommendation

For production, use a dedicated service account (for example, `mcp-bot`) for MCP automation.

- Do not use a personal owner/admin account for long-lived automation.
- Grant only the permissions required by enabled tool groups:
  - records tools: object read/write operations
  - metadata tools: object/field administration
  - workflow tools: workflow and workflow-version mutations
- Store credentials in a secrets manager.
- Rotate service-account credentials on a schedule.
- Use `TWENTY_AUTH_STRICT_USER_AUTH=true` to avoid silent fallback to weaker auth scope.

## Deployment compatibility

- The server is tested primarily against a self-hosted Twenty deployment.
- It can also work with cloud-hosted Twenty workspaces when the same REST and GraphQL endpoints are available to your credentials.
- If your workspace adds auth gateways (SSO-only, captcha, proxy restrictions), you may need to adapt auth settings or network headers.

With user session enabled, the server:

1. calls `getLoginTokenFromCredentials`,
2. exchanges via `getAuthTokensFromLoginToken`,
3. uses access token for requests,
4. renews via `renewToken`,
5. relogs if renewal fails.

Set `TWENTY_AUTH_STRICT_USER_AUTH=true` to prevent silent fallback to API key scope.

## Environment variables

See `env.sample`.

Minimal recommended setup:

```bash
TWENTY_BASE_URL="https://crm.example.com"
TWENTY_AUTH_EMAIL="admin@example.com"
TWENTY_AUTH_PASSWORD="replace_me"
TWENTY_AUTH_ORIGIN="https://crm.example.com"
TWENTY_AUTH_STRICT_USER_AUTH="true"
```

## MCP client configuration

Example `~/.config/opencode/opencode.json` block:

```json
{
  "mcp": {
    "twenty-crm": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "@neutralthiscrazy/twenty-crm-mcp-server"
      ],
      "enabled": true,
      "environment": {
        "TWENTY_BASE_URL": "https://crm.example.com",
        "TWENTY_AUTH_EMAIL": "admin@example.com",
        "TWENTY_AUTH_PASSWORD": "replace_me",
        "TWENTY_AUTH_ORIGIN": "https://crm.example.com",
        "TWENTY_AUTH_REFRESH_SKEW_SEC": "120",
        "TWENTY_AUTH_STRICT_USER_AUTH": "true",
        "TWENTY_TIMEOUT_MS": "30000",
        "TWENTY_RETRY_MAX_ATTEMPTS": "4",
        "TWENTY_RETRY_BASE_DELAY_MS": "500",
        "TWENTY_RETRY_MAX_DELAY_MS": "8000",
        "TWENTY_RETRY_JITTER_RATIO": "0.25",
        "TWENTY_METADATA_TIMEOUT_MS": "120000",
        "TWENTY_METADATA_COOLDOWN_MS": "2000",
        "TWENTY_READINESS_POLL_INTERVAL_MS": "5000",
        "TWENTY_READINESS_MAX_WAIT_MS": "120000"
      }
    }
  }
}
```

## Tool groups

### Records

- `records_list`
- `records_get`
- `records_create`
- `records_update`
- `records_delete`
- `records_upsert_batch`

### Metadata

- `meta_list_objects`
- `meta_get_object`
- `meta_get_field`
- `meta_icon_catalog`
- `meta_find_dependencies`
- `meta_create_object`
- `meta_update_object`
- `meta_set_object_active`
- `meta_delete_object`
- `meta_create_fields_batch`
- `meta_update_field`
- `meta_set_field_active`
- `meta_delete_field`

### Schema-as-code

- `schema_export`
- `schema_diff`
- `schema_apply`

### Workflows

- `workflow_get`
- `workflow_validate_definition`
- `workflow_create_from_definition`
- `workflow_update_from_definition`
- `workflow_activate_version`
- `workflow_deactivate_version`

### Escape hatch

- `graphql_query`

## Workflow scope notes

- User-session auth is strongly recommended for workflow mutations.
- API key auth may be insufficient for step-level operations in some workspaces.
- Automated trigger sync handles known Twenty payload inconsistency (`workflow` vs `workflowId`) and returns explicit skip details when Twenty rejects all variants.

## Safety and error model

- Destructive delete tools require `confirm: "DELETE"`.
- Schema apply execution requires `confirm: "APPLY"` when `dryRun=false`.
- Metadata mutations are serialized server-side to avoid concurrent Twenty schema-rebuild crashes.
- Use `meta_create_fields_batch` for field creation (including single-field creation).
- Errors are normalized to:
  - `error`
  - `category`
  - `code`
  - `status`
  - `retryable`
  - `details`

## Local development

```bash
git clone https://github.com/Neutralthiscrazy/twenty-crm-mcp-server.git
cd twenty-crm-mcp-server
npm install
npm run check
```

Run locally:

```bash
TWENTY_BASE_URL="https://crm.example.com" \
TWENTY_AUTH_EMAIL="admin@example.com" \
TWENTY_AUTH_PASSWORD="replace_me" \
TWENTY_AUTH_STRICT_USER_AUTH="true" \
node src/index.js
```

## Security

- Never commit real credentials, tokens, or workspace-specific secrets.
- Use placeholders in config examples.
- For disclosure process, see [SECURITY.md](SECURITY.md).

## Documentation

- [Architecture](docs/ARCHITECTURE.md)
- [Authentication](docs/AUTHENTICATION.md)
- [Workflow behavior](docs/WORKFLOWS.md)
- [Development guide](docs/DEVELOPMENT.md)
- [Deployment guide](docs/DEPLOYMENT.md)
- [API implementation notes](TWENTY_API_NOTES.md)

## Contributing

Contributions are welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md) before opening a pull request.

## License

MIT - see [LICENSE](LICENSE).