MCP Server

twenty

io.usefulapi/twenty
Business & Operations Sales & CRM Public & reachable MCP 2026-07-28

What this MCP does

Manages Twenty CRM records for people, companies, opportunities, notes, and tasks, including listing, creation, and updates.

twenty_create_company
Create company
Create a new company. `name` is required. Twenty REST: POST /rest/companies.
Destructive
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['name'], 'properties': {'name': {'type': 'string', 'description': 'The company name (required).'}, 'xUrl': {'type': 'string', 'description': 'X/Twitter URL (sent as xLink:{primaryLinkUrl}).'}, 'extra': {'type': 'object', 'description': 'Passthrough object of additional/custom fields merged into the request body verbatim.', 'propertyNames': {'type': 'string'}, 'additionalProperties': {}}, 'employees': {'type': 'number', 'description': 'Employee count.'}, 'domainName': {'type': 'string', 'description': 'Primary domain / website URL (sent as domainName:{primaryLinkUrl}).'}, 'addressCity': {'type': 'string', 'description': 'City (sent as address:{addressCity}).'}, 'linkedinUrl': {'type': 'string', 'description': 'LinkedIn URL (sent as linkedinLink:{primaryLinkUrl}).'}, 'idealCustomerProfile': {'type': 'boolean', 'description': 'Whether this company matches the ideal customer profile.'}}}
twenty_create_note
Create note
Create a note. `title` is required; `body` holds the note content. (Attaching to records via noteTargets is out of scope.) Twenty REST: POST /rest/notes.
Destructive
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['title'], 'properties': {'body': {'type': 'string', 'description': 'The note content/body.'}, 'extra': {'type': 'object', 'description': 'Passthrough object of additional/custom fields merged into the request body verbatim.', 'propertyNames': {'type': 'string'}, 'additionalProperties': {}}, 'title': {'type': 'string', 'description': 'The note title (required).'}}}
twenty_create_opportunity
Create opportunity
Create a new opportunity (deal). `name` is required; amountMicros combines with currencyCode into amount:{amountMicros,currencyCode}. Twenty REST: POST /rest/opportunities.
Destructive
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['name'], 'properties': {'name': {'type': 'string', 'description': 'The opportunity name (required).'}, 'extra': {'type': 'object', 'description': 'Passthrough object of additional/custom fields merged into the request body verbatim.', 'propertyNames': {'type': 'string'}, 'additionalProperties': {}}, 'stage': {'type': 'string', 'description': 'Pipeline stage — e.g. SCREENING, MEETING, PROPOSAL, NEGOTIATION, CUSTOMER (custom pipelines vary).'}, 'closeDate': {'type': 'string', 'description': 'Expected close date (ISO 8601).'}, 'companyId': {'type': 'string', 'description': 'Id of the associated company.'}, 'amountMicros': {'type': 'number', 'description': 'Opportunity amount in micros (× 1,000,000). Sent as amount:{amountMicros,currencyCode}.'}, 'currencyCode': {'type': 'string', 'default': 'USD', 'description': 'Currency code for the amount (default USD; only sent when amountMicros is provided).'}, 'pointOfContactId': {'type': 'string', 'description': 'Id of the point-of-contact person.'}}}
twenty_create_person
Create person
Create a new person (contact). All fields optional; firstName/lastName combine into name:{firstName,lastName}. Twenty REST: POST /rest/people.
Destructive
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'city': {'type': 'string', 'description': 'City.'}, 'xUrl': {'type': 'string', 'description': 'X/Twitter URL (sent as xLink:{primaryLinkUrl}).'}, 'extra': {'type': 'object', 'description': 'Passthrough object of additional/custom fields merged into the request body verbatim.', 'propertyNames': {'type': 'string'}, 'additionalProperties': {}}, 'jobTitle': {'type': 'string', 'description': 'Job title.'}, 'lastName': {'type': 'string', 'description': 'Last name (combined into name:{firstName,lastName}).'}, 'companyId': {'type': 'string', 'description': 'Id of the company to link this person to.'}, 'firstName': {'type': 'string', 'description': 'First name (combined into name:{firstName,lastName}).'}, 'linkedinUrl': {'type': 'string', 'description': 'LinkedIn URL (sent as linkedinLink:{primaryLinkUrl}).'}, 'primaryEmail': {'type': 'string', 'description': 'Primary email address (sent as emails:{primaryEmail}).'}, 'primaryPhone': {'type': 'string', 'description': 'Primary phone number (sent as phones:{primaryPhoneNumber}).'}}}
twenty_create_task
Create task
Create a task. `title` is required. Twenty REST: POST /rest/tasks.
Destructive
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['title'], 'properties': {'body': {'type': 'string', 'description': 'Task body / description.'}, 'dueAt': {'type': 'string', 'description': 'Due date/time (ISO 8601).'}, 'extra': {'type': 'object', 'description': 'Passthrough object of additional/custom fields merged into the request body verbatim.', 'propertyNames': {'type': 'string'}, 'additionalProperties': {}}, 'title': {'type': 'string', 'description': 'The task title (required).'}, 'status': {'type': 'string', 'description': 'Task status — e.g. TODO, IN_PROGRESS, DONE.'}, 'assigneeId': {'type': 'string', 'description': 'Id of the workspace member assigned to the task.'}}}
twenty_get_company
Get company
Get a single company by id. Twenty REST: GET /rest/companies/{id}.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['id'], 'properties': {'id': {'type': 'string', 'description': 'The company id.'}, 'depth': {'type': 'integer', 'maximum': 2, 'minimum': 0, 'description': 'How deep to hydrate related records: 0, 1, or 2.'}}}
twenty_get_note
Get note
Get a single note by id. Twenty REST: GET /rest/notes/{id}.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['id'], 'properties': {'id': {'type': 'string', 'description': 'The note id.'}, 'depth': {'type': 'integer', 'maximum': 2, 'minimum': 0, 'description': 'How deep to hydrate related records: 0, 1, or 2.'}}}
twenty_get_opportunity
Get opportunity
Get a single opportunity by id. Twenty REST: GET /rest/opportunities/{id}.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['id'], 'properties': {'id': {'type': 'string', 'description': 'The opportunity id.'}, 'depth': {'type': 'integer', 'maximum': 2, 'minimum': 0, 'description': 'How deep to hydrate related records: 0, 1, or 2.'}}}
twenty_get_person
Get person
Get a single person (contact) by id. Twenty REST: GET /rest/people/{id}.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['id'], 'properties': {'id': {'type': 'string', 'description': 'The person id.'}, 'depth': {'type': 'integer', 'maximum': 2, 'minimum': 0, 'description': 'How deep to hydrate related records: 0, 1, or 2.'}}}
twenty_get_task
Get task
Get a single task by id. Twenty REST: GET /rest/tasks/{id}.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['id'], 'properties': {'id': {'type': 'string', 'description': 'The task id.'}, 'depth': {'type': 'integer', 'maximum': 2, 'minimum': 0, 'description': 'How deep to hydrate related records: 0, 1, or 2.'}}}
twenty_list_companies
List companies
List/filter companies. Supports cursor pagination, raw filter/order_by, and relation depth. Twenty REST: GET /rest/companies.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'depth': {'type': 'integer', 'maximum': 2, 'minimum': 0, 'description': 'How deep to hydrate related records: 0, 1, or 2.'}, 'limit': {'type': 'integer', 'maximum': 60, 'minimum': 1, 'description': 'Results per page (1-60, default 20 — Twenty caps at 60).'}, 'filter': {'type': 'string', 'description': 'Raw Twenty filter string, passed verbatim as ?filter=. Syntax: field[comparator]:value, e.g. `employees[gte]:100` or `stage[eq]:"MEETING"`. Comparators: eq, neq, gt, gte, lt, lte, in, is, like, ilike, startsWith.'}, 'order_by': {'type': 'string', 'description': 'Raw Twenty ordering string, passed verbatim as ?order_by=, e.g. `createdAt[DescNullsLast]`.'}, 'ending_before': {'type': 'string', 'description': "Pagination cursor — return records before this cursor (from a previous page's pageInfo)."}, 'starting_after': {'type': 'string', 'description': "Pagination cursor — return records after this cursor (from a previous page's pageInfo)."}}}
twenty_list_metadata_objects
List metadata objects
List all objects (standard + custom) and their fields from the Twenty schema — use this to discover custom objects/fields and valid field names. Twenty REST: GET /rest/metadata/objects.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {}}
twenty_list_notes
List notes
List/filter notes. Supports cursor pagination, raw filter/order_by, and relation depth. Twenty REST: GET /rest/notes.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'depth': {'type': 'integer', 'maximum': 2, 'minimum': 0, 'description': 'How deep to hydrate related records: 0, 1, or 2.'}, 'limit': {'type': 'integer', 'maximum': 60, 'minimum': 1, 'description': 'Results per page (1-60, default 20 — Twenty caps at 60).'}, 'filter': {'type': 'string', 'description': 'Raw Twenty filter string, passed verbatim as ?filter=. Syntax: field[comparator]:value, e.g. `employees[gte]:100` or `stage[eq]:"MEETING"`. Comparators: eq, neq, gt, gte, lt, lte, in, is, like, ilike, startsWith.'}, 'order_by': {'type': 'string', 'description': 'Raw Twenty ordering string, passed verbatim as ?order_by=, e.g. `createdAt[DescNullsLast]`.'}, 'ending_before': {'type': 'string', 'description': "Pagination cursor — return records before this cursor (from a previous page's pageInfo)."}, 'starting_after': {'type': 'string', 'description': "Pagination cursor — return records after this cursor (from a previous page's pageInfo)."}}}
twenty_list_opportunities
List opportunities
List/filter opportunities (deals). Supports cursor pagination, raw filter/order_by, and relation depth. Twenty REST: GET /rest/opportunities.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'depth': {'type': 'integer', 'maximum': 2, 'minimum': 0, 'description': 'How deep to hydrate related records: 0, 1, or 2.'}, 'limit': {'type': 'integer', 'maximum': 60, 'minimum': 1, 'description': 'Results per page (1-60, default 20 — Twenty caps at 60).'}, 'filter': {'type': 'string', 'description': 'Raw Twenty filter string, passed verbatim as ?filter=. Syntax: field[comparator]:value, e.g. `employees[gte]:100` or `stage[eq]:"MEETING"`. Comparators: eq, neq, gt, gte, lt, lte, in, is, like, ilike, startsWith.'}, 'order_by': {'type': 'string', 'description': 'Raw Twenty ordering string, passed verbatim as ?order_by=, e.g. `createdAt[DescNullsLast]`.'}, 'ending_before': {'type': 'string', 'description': "Pagination cursor — return records before this cursor (from a previous page's pageInfo)."}, 'starting_after': {'type': 'string', 'description': "Pagination cursor — return records after this cursor (from a previous page's pageInfo)."}}}
twenty_list_people
List people
List/filter people (contacts). Supports cursor pagination, raw filter/order_by, and relation depth. Twenty REST: GET /rest/people.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'depth': {'type': 'integer', 'maximum': 2, 'minimum': 0, 'description': 'How deep to hydrate related records: 0, 1, or 2.'}, 'limit': {'type': 'integer', 'maximum': 60, 'minimum': 1, 'description': 'Results per page (1-60, default 20 — Twenty caps at 60).'}, 'filter': {'type': 'string', 'description': 'Raw Twenty filter string, passed verbatim as ?filter=. Syntax: field[comparator]:value, e.g. `employees[gte]:100` or `stage[eq]:"MEETING"`. Comparators: eq, neq, gt, gte, lt, lte, in, is, like, ilike, startsWith.'}, 'order_by': {'type': 'string', 'description': 'Raw Twenty ordering string, passed verbatim as ?order_by=, e.g. `createdAt[DescNullsLast]`.'}, 'ending_before': {'type': 'string', 'description': "Pagination cursor — return records before this cursor (from a previous page's pageInfo)."}, 'starting_after': {'type': 'string', 'description': "Pagination cursor — return records after this cursor (from a previous page's pageInfo)."}}}
twenty_list_tasks
List tasks
List/filter tasks. Supports cursor pagination, raw filter/order_by, and relation depth. Twenty REST: GET /rest/tasks.
Read only
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'depth': {'type': 'integer', 'maximum': 2, 'minimum': 0, 'description': 'How deep to hydrate related records: 0, 1, or 2.'}, 'limit': {'type': 'integer', 'maximum': 60, 'minimum': 1, 'description': 'Results per page (1-60, default 20 — Twenty caps at 60).'}, 'filter': {'type': 'string', 'description': 'Raw Twenty filter string, passed verbatim as ?filter=. Syntax: field[comparator]:value, e.g. `employees[gte]:100` or `stage[eq]:"MEETING"`. Comparators: eq, neq, gt, gte, lt, lte, in, is, like, ilike, startsWith.'}, 'order_by': {'type': 'string', 'description': 'Raw Twenty ordering string, passed verbatim as ?order_by=, e.g. `createdAt[DescNullsLast]`.'}, 'ending_before': {'type': 'string', 'description': "Pagination cursor — return records before this cursor (from a previous page's pageInfo)."}, 'starting_after': {'type': 'string', 'description': "Pagination cursor — return records after this cursor (from a previous page's pageInfo)."}}}
twenty_update_company
Update company
Update fields on an existing company. Only provided fields change. Twenty REST: PATCH /rest/companies/{id}.
Destructive
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['id'], 'properties': {'id': {'type': 'string', 'description': 'The company id to update.'}, 'name': {'type': 'string', 'description': 'The company name.'}, 'xUrl': {'type': 'string', 'description': 'X/Twitter URL (sent as xLink:{primaryLinkUrl}).'}, 'extra': {'type': 'object', 'description': 'Passthrough object of additional/custom fields merged into the request body verbatim.', 'propertyNames': {'type': 'string'}, 'additionalProperties': {}}, 'employees': {'type': 'number', 'description': 'Employee count.'}, 'domainName': {'type': 'string', 'description': 'Primary domain / website URL (sent as domainName:{primaryLinkUrl}).'}, 'addressCity': {'type': 'string', 'description': 'City (sent as address:{addressCity}).'}, 'linkedinUrl': {'type': 'string', 'description': 'LinkedIn URL (sent as linkedinLink:{primaryLinkUrl}).'}, 'idealCustomerProfile': {'type': 'boolean', 'description': 'Whether this company matches the ideal customer profile.'}}}
twenty_update_opportunity
Update opportunity
Update fields on an existing opportunity. Only provided fields change. Twenty REST: PATCH /rest/opportunities/{id}.
Destructive
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['id'], 'properties': {'id': {'type': 'string', 'description': 'The opportunity id to update.'}, 'name': {'type': 'string', 'description': 'The opportunity name.'}, 'extra': {'type': 'object', 'description': 'Passthrough object of additional/custom fields merged into the request body verbatim.', 'propertyNames': {'type': 'string'}, 'additionalProperties': {}}, 'stage': {'type': 'string', 'description': 'Pipeline stage — e.g. SCREENING, MEETING, PROPOSAL, NEGOTIATION, CUSTOMER (custom pipelines vary).'}, 'closeDate': {'type': 'string', 'description': 'Expected close date (ISO 8601).'}, 'companyId': {'type': 'string', 'description': 'Id of the associated company.'}, 'amountMicros': {'type': 'number', 'description': 'Opportunity amount in micros (× 1,000,000). Sent as amount:{amountMicros,currencyCode}.'}, 'currencyCode': {'type': 'string', 'default': 'USD', 'description': 'Currency code for the amount (default USD; only sent when amountMicros is provided).'}, 'pointOfContactId': {'type': 'string', 'description': 'Id of the point-of-contact person.'}}}
twenty_update_person
Update person
Update fields on an existing person. Only provided fields change. Twenty REST: PATCH /rest/people/{id}.
Destructive
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['id'], 'properties': {'id': {'type': 'string', 'description': 'The person id to update.'}, 'city': {'type': 'string', 'description': 'City.'}, 'xUrl': {'type': 'string', 'description': 'X/Twitter URL (sent as xLink:{primaryLinkUrl}).'}, 'extra': {'type': 'object', 'description': 'Passthrough object of additional/custom fields merged into the request body verbatim.', 'propertyNames': {'type': 'string'}, 'additionalProperties': {}}, 'jobTitle': {'type': 'string', 'description': 'Job title.'}, 'lastName': {'type': 'string', 'description': 'Last name (combined into name:{firstName,lastName}).'}, 'companyId': {'type': 'string', 'description': 'Id of the company to link this person to.'}, 'firstName': {'type': 'string', 'description': 'First name (combined into name:{firstName,lastName}).'}, 'linkedinUrl': {'type': 'string', 'description': 'LinkedIn URL (sent as linkedinLink:{primaryLinkUrl}).'}, 'primaryEmail': {'type': 'string', 'description': 'Primary email address (sent as emails:{primaryEmail}).'}, 'primaryPhone': {'type': 'string', 'description': 'Primary phone number (sent as phones:{primaryPhoneNumber}).'}}}
twenty_update_task
Update task
Update fields on an existing task. Only provided fields change. Twenty REST: PATCH /rest/tasks/{id}.
Destructive
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['id'], 'properties': {'id': {'type': 'string', 'description': 'The task id to update.'}, 'body': {'type': 'string', 'description': 'Task body / description.'}, 'dueAt': {'type': 'string', 'description': 'Due date/time (ISO 8601).'}, 'extra': {'type': 'object', 'description': 'Passthrough object of additional/custom fields merged into the request body verbatim.', 'propertyNames': {'type': 'string'}, 'additionalProperties': {}}, 'title': {'type': 'string', 'description': 'The task title.'}, 'status': {'type': 'string', 'description': 'Task status — e.g. TODO, IN_PROGRESS, DONE.'}, 'assigneeId': {'type': 'string', 'description': 'Id of the workspace member assigned to the task.'}}}
Changed
twenty_update_task
Oct. 1, 2026, 2:42 a.m.
Changed
twenty_create_task
Oct. 1, 2026, 2:42 a.m.
Changed
twenty_create_note
Oct. 1, 2026, 2:42 a.m.
Changed
twenty_update_opportunity
Oct. 1, 2026, 2:42 a.m.
Changed
twenty_create_opportunity
Oct. 1, 2026, 2:42 a.m.
Changed
twenty_update_company
Oct. 1, 2026, 2:42 a.m.
Changed
twenty_create_company
Oct. 1, 2026, 2:42 a.m.
Changed
twenty_update_person
Oct. 1, 2026, 2:42 a.m.
Changed
twenty_create_person
Oct. 1, 2026, 2:42 a.m.
Changed
twenty_get_task
Oct. 1, 2026, 2:42 a.m.
Changed
twenty_list_tasks
Oct. 1, 2026, 2:42 a.m.
Changed
twenty_get_note
Oct. 1, 2026, 2:42 a.m.
Changed
twenty_list_notes
Oct. 1, 2026, 2:42 a.m.
Changed
twenty_get_opportunity
Oct. 1, 2026, 2:42 a.m.
Changed
twenty_list_opportunities
Oct. 1, 2026, 2:42 a.m.
Changed
twenty_get_company
Oct. 1, 2026, 2:42 a.m.
Changed
twenty_list_companies
Oct. 1, 2026, 2:42 a.m.
Changed
twenty_get_person
Oct. 1, 2026, 2:42 a.m.
Changed
twenty_list_people
Oct. 1, 2026, 2:42 a.m.
Changed
twenty_list_metadata_objects
Oct. 1, 2026, 2:42 a.m.
Added
twenty_update_task
Sept. 25, 2026, 2:44 a.m.
Added
twenty_create_task
Sept. 25, 2026, 2:44 a.m.
Added
twenty_create_note
Sept. 25, 2026, 2:44 a.m.
Added
twenty_update_opportunity
Sept. 25, 2026, 2:44 a.m.
Added
twenty_create_opportunity
Sept. 25, 2026, 2:44 a.m.
Added
twenty_update_company
Sept. 25, 2026, 2:44 a.m.
Added
twenty_create_company
Sept. 25, 2026, 2:44 a.m.
Added
twenty_update_person
Sept. 25, 2026, 2:44 a.m.
Added
twenty_create_person
Sept. 25, 2026, 2:44 a.m.
Added
twenty_get_task
Sept. 25, 2026, 2:44 a.m.