A ground-up revision of the server against the real Twenty REST API, incorporating fixes and features contributed by the community in PRs #4, #6, #7 and #8 and several forks.
Fixed
- Writes work again. Flat params (
firstName,email,phone,linkedinUrl,domainName,address, revenue/amount fields) are now mapped to Twenty's composite field shapes (name,emails,phones, link/address/currency composites). Previously everycreate_person/update_personand most company writes returned HTTP 400. (Closes the regression tracked in #2; based on #4 by @zaks.) - Search works again. Twenty's REST API has no
searchquery param — it was silently ignored, sosearch/search_recordsreturned unfiltered lists. Search now buildsor(...[ilike]:%term%...)filters over per-object field sets, with grammar-safe sanitization. (Based on #6 by @studio7A and #8 by @InDebted-Growth.) - Pagination is now real.
offset(also silently ignored by the API) was replaced with Twenty's cursor pagination:startingAfter/endingBefore, and list results exposepageInfo. - Updates use
PATCH(Twenty's documented verb) instead ofPUT. - Note/task bodies write to
bodyV2: { markdown }— plainbodyno longer exists on current Twenty versions. DELETEresponses with empty bodies no longer throw (204/empty-body handling; based on @ndrkltsk's fork).- Structured Twenty error bodies are parsed into readable messages instead of raw JSON dumps.
Added
- Opportunity tools:
create_opportunity,get_opportunity,list_opportunities,update_opportunity,delete_opportunity, with automaticamountMicrosconversion. (Based on #7 by @tarikhennen.) - Record targets:
create_noteandcreate_taskacceptpersonId/companyId/opportunityIdand create thenoteTargets/taskTargetslinks automatically. - Batch creates:
batch_create_peopleandbatch_create_companies(up to 60 records per call). list_workspace_membersfor resolving taskassigneeId.filter,orderByanddepthpassthrough params on all list tools;depthon all get tools.- Retry with exponential backoff on 429/5xx (honoring
Retry-After) and 30s request timeouts. - Unit test suite (
npm test,node --test, no network required) and GitHub Actions CI. Dockerfile,LICENSEfile,binentry (npx -y github:mhenry3164/twenty-crm-mcp-server).- Support for both
annualRecurringRevenue(Twenty ≤ v1.x field name) andannualRevenue(v2.x+). TWENTY_DEFAULT_CURRENCYenv var (defaultUSD).
Changed
- Upgraded
@modelcontextprotocol/sdkfrom ^0.6.0 to ^1.30.0. - List results are returned as
{ records, pageInfo, totalCount? }instead of the raw API envelope. - Errors from tool calls are flagged with
isError: truein the MCP response.
Breaking
offsetremoved from list tools (it never worked — usestartingAfter).positionparams removed from note/task tools.assigneeIdon tasks is documented as a workspace member ID (it always was one — the old description said "person").
Full changelog: https://github.com/mhenry3164/twenty-crm-mcp-server/blob/main/CHANGELOG.md