Some checks failed
App Prod-Parity E2E Dispatch / dispatch (push) Failing after 10s
CD Storybook UI / build (push) Failing after 3m25s
CD Storybook UI / dispatch (push) Has been skipped
CD deploy main / website-changed-files (push) Successful in 18m8s
CI Agent Skills / changed-files-check (push) Successful in 18m9s
CI Create App E2E minimal / changed-files-check (push) Successful in 24s
CI Create App / changed-files-check (push) Successful in 26s
CI Docs / changed-files-check (push) Successful in 26s
CI Emails / changed-files-check (push) Successful in 28s
CI Example App Hello World / changed-files-check (push) Successful in 23s
CI Front / changed-files-check (push) Has been skipped
CI Example App Postcard / changed-files-check (push) Successful in 27s
CI UI / changed-files-check (push) Has been skipped
CI Utils Test / changed-files-check (push) Successful in 45s
CI Twenty Apps / discover (push) Successful in 1m3s
CD deploy main / deploy-main (push) Failing after 3s
CI Agent Skills / agent-skills-validate (push) Has been skipped
CI Create App / create-app-test (lint) (push) Has been skipped
CI Emails / emails-test (push) Has been skipped
CI Front / front-task (lingui:compile) (push) Has been skipped
CI Front / front-task (lint) (push) Has been skipped
CI Example App Postcard / example-app-postcard (push) Has been skipped
CI UI / ui-task (lint) (push) Has been skipped
CI UI / ui-task (pack-size) (push) Has been skipped
CI UI / ui-task (size) (push) Has been skipped
CI UI / ui-task (test) (push) Has been skipped
CI UI / ui-task (typecheck) (push) Has been skipped
CI Utils Test / utils-test (push) Has been skipped
CI Twenty Apps / ${{ matrix.app.name }} (push) Has been skipped
CI Emails / ci-emails-status-check (push) Successful in 2s
CI Example App Hello World / ci-example-app-hello-world-status-check (push) Successful in 2s
CI Example App Postcard / ci-example-app-postcard-status-check (push) Successful in 3s
CI UI / ui-sb-test (push) Has been skipped
CI Utils Test / ci-utils-test-status-check (push) Successful in 2s
CI Twenty Apps / ci-twenty-apps-status-check (push) Successful in 2s
CI UI / ci-ui-status-check (push) Successful in 2s
CI Desktop / desktop (push) Failing after 1m8s
Push docs to Crowdin / Push documentation to Crowdin (push) Failing after 55s
Push translations to Crowdin / Extract and upload translations (push) Failing after 5s
Push website translations to Crowdin / Extract and upload website translations (push) Failing after 5s
CI Create App / create-app-test (test) (push) Has been skipped
CI Create App / create-app-test (typecheck) (push) Has been skipped
CI Docs / docs-lint (push) Has been skipped
CI Example App Hello World / example-app-hello-world (push) Has been skipped
CI Front / front-task (lingui:extract) (push) Has been skipped
CI Front / front-task (test) (push) Has been skipped
CI Front / front-task (typecheck) (push) Has been skipped
CI UI / ui-sb-build (push) Failing after 1m32s
CI Twenty Apps / ${{ matrix.app.name }} (${{ matrix.server-source }}) (push) Has been skipped
CI Agent Skills / agent-skills-publish (push) Has been skipped
CI Create App / ci-create-app-status-check (push) Successful in 2s
CI Agent Skills / agent-skills-remote-source (push) Has been skipped
CI Create App E2E minimal / create-app-e2e-minimal (push) Has been cancelled
CI E2E Main / e2e-test (push) Has been cancelled
CI Front / front-sb-build (push) Has been cancelled
CI Front / front-build (push) Has been cancelled
CI Create App E2E minimal / ci-create-app-e2e-minimal-status-check (push) Has been cancelled
CI E2E Main / ci-e2e-main-status-check (push) Has been cancelled
CI E2E Main / notify-main-ci-failure (push) Has been cancelled
CI E2E Main / qa-scout-comment (push) Has been cancelled
CI Front / front-sb-test (push) Has been cancelled
CI Front / front-sb-screenshots (push) Has been cancelled
CI Front / ci-front-status-check (push) Has been cancelled
DPA Sub-Processor Sync / sync-subprocessors (push) Failing after 3s
AI Catalog Sync / sync-catalog (push) Failing after 2s
135 lines
5.4 KiB
Plaintext
135 lines
5.4 KiB
Plaintext
---
|
|
title: MCP Server
|
|
description: Connect AI assistants to your Twenty workspace using the Model Context Protocol.
|
|
---
|
|
|
|
Twenty exposes an [MCP](https://modelcontextprotocol.io/) server so that AI assistants — Claude Desktop, Claude Code, Cursor, ChatGPT, and others — can read and write your CRM data through natural language.
|
|
|
|
Use your **workspace URL** (the URL you use to access Twenty) as the MCP endpoint. On Twenty Cloud, your workspace URL might be `https://{mycompany}.twenty.com` or a custom domain. The server is available at:
|
|
|
|
| Environment | MCP Endpoint |
|
|
|-------------|-------------|
|
|
| **Cloud** | `https://{your-workspace-url}/mcp` (e.g. `https://mycompany.twenty.com/mcp`) |
|
|
| **Self-Hosted** | `https://{your-domain}/mcp` |
|
|
|
|
## Authentication Methods
|
|
|
|
You have two ways to authenticate your MCP client: **OAuth** (recommended) or **API Key**.
|
|
|
|
### Option A — OAuth (Recommended)
|
|
|
|
With OAuth, your MCP client opens a browser window for you to log in. No secrets are stored in config files, and tokens refresh automatically.
|
|
|
|
<Note>
|
|
OAuth requires an MCP client that supports the [MCP Authorization specification](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization). Claude Desktop, Claude Code, Cursor, and ChatGPT support it.
|
|
</Note>
|
|
|
|
Add this to your MCP client configuration, replacing `{your-workspace-url}` with your workspace host (e.g. `mycompany.twenty.com`):
|
|
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"twenty": {
|
|
"type": "streamable-http",
|
|
"url": "https://{your-workspace-url}/mcp"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
That's it — no API key needed. When the client connects for the first time it will:
|
|
|
|
1. Discover Twenty's OAuth metadata via `/.well-known/oauth-protected-resource` and `/.well-known/oauth-authorization-server`
|
|
2. Register itself as an OAuth client via dynamic client registration (RFC 7591)
|
|
3. Open your browser to authorize access
|
|
4. Receive tokens and connect to the MCP server
|
|
|
|
Subsequent connections reuse the stored tokens and refresh them automatically.
|
|
|
|
### Option B — API Key
|
|
|
|
If your MCP client does not support OAuth, or you prefer static credentials, pass an API key in the `Authorization` header:
|
|
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"twenty": {
|
|
"type": "streamable-http",
|
|
"url": "https://{your-workspace-url}/mcp",
|
|
"headers": {
|
|
"Authorization": "Bearer YOUR_API_KEY"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
<Warning>
|
|
Your API key grants access to workspace data. Keep it out of version control and shared dotfiles.
|
|
</Warning>
|
|
|
|
To create an API key, go to **Settings → MCP & APIs → API → + Create key**. See [APIs](/developers/extend/api#create-an-api-key) for details.
|
|
|
|
## Quick Start
|
|
|
|
### 1. Copy the config
|
|
|
|
Go to **Settings → MCP & APIs → MCP** in Twenty. Choose your authentication method (OAuth or API Key), copy the JSON snippet (it will already use your workspace URL), and paste it into your MCP client's config file.
|
|
|
|
| Client | Config file location |
|
|
|--------|---------------------|
|
|
| **Claude Desktop** | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows) |
|
|
| **Claude Code** | `~/.claude.json` (user) or `.mcp.json` (project) |
|
|
| **Cursor** | `.cursor/mcp.json` in your project, or `~/.cursor/mcp.json` globally |
|
|
| **ChatGPT** | Turn on Developer Mode in **Settings → Apps & Connectors → Advanced settings**, then use **Create** in **Settings → Apps & Connectors** to add the MCP server |
|
|
|
|
### 2. Connect
|
|
|
|
Restart your MCP client (or reload the config). If using OAuth you will be redirected to Twenty to authorize access. If using an API key the connection is immediate.
|
|
|
|
### 3. Start using it
|
|
|
|
Ask your AI assistant to interact with your CRM:
|
|
|
|
- *"Show me the 5 most recently created companies"*
|
|
- *"Create a new person named Jane Doe at Acme Corp"*
|
|
- *"Find all open opportunities worth more than $10k"*
|
|
|
|
## Available Tools
|
|
|
|
Once connected, the MCP server exposes tools that mirror the Twenty API. The recommended workflow is:
|
|
|
|
1. **`learn_tools`** — get the input schema for specific tools
|
|
2. **`execute_tool`** — run a tool
|
|
|
|
You don't need to remember tool names. Ask your AI assistant what it can do and it will call `learn_tools` automatically.
|
|
|
|
## Permissions
|
|
|
|
MCP connections inherit the permissions of the authenticated user (OAuth) or the role assigned to the API key. To restrict what the MCP server can do:
|
|
|
|
- **OAuth**: The user's workspace role applies.
|
|
- **API Key**: Assign a role to the API key under **Settings → Members → Roles**. See [Permissions](/user-guide/permissions-access/capabilities/permissions).
|
|
|
|
## Self-Hosted Configuration
|
|
|
|
For self-hosted instances, replace `{your-workspace-url}` with your server URL. Make sure `SERVER_URL` in your environment matches the public URL of your Twenty instance — this is used to generate the OAuth discovery metadata.
|
|
|
|
```bash
|
|
SERVER_URL=https://twenty.yourcompany.com
|
|
```
|
|
|
|
The MCP endpoint, OAuth endpoints, and discovery metadata all derive from this value.
|
|
|
|
## Troubleshooting
|
|
|
|
**"Unauthorized" or 401 errors**
|
|
- OAuth: re-authorize by clearing the stored tokens in your MCP client and reconnecting.
|
|
- API Key: verify the key is valid and hasn't expired. Regenerate it if needed.
|
|
|
|
**OAuth flow doesn't open a browser**
|
|
- Ensure your MCP client supports MCP Authorization. Fall back to the API Key method if it doesn't.
|
|
|
|
**Connection timeout**
|
|
- Confirm the MCP endpoint URL is reachable from your machine. For self-hosted instances, check that the server is running and `SERVER_URL` is set correctly.
|