mattrguerra/meridian-crm-mcpmainPrivate on GitHub, published here in full

CHANGELOG.md

Language Markdown11.8 KB251 lines

CHANGELOG.md

  1. # Changelog
  2. Newest first. Tool contracts (names, parameters and docstrings) are listed
  3. where they changed; everything else is internal.
  4. ## Unreleased
  5. Internal cleanup; no tool, parameter, docstring, reply or configuration
  6. changes (the 30-tool contract is now pinned by `tests/tool_api.json`).
  7. - The version history moved out of the `server.py` docstring into this file.
  8. - Shared helpers replace repeated code: record-id validation, the write
  9. guards (a decorator on each write tool), local timestamp display, stage
  10. lookup and name joining; one user cache instead of two; the contact and
  11. company create/update tools share one implementation.
  12. - Imports that sat inside functions are at the top of the module.
  13. - Added `pyproject.toml` (ruff and pytest settings), unit tests with a faked
  14. Bitrix client and `httpx.MockTransport`, and a CI workflow.
  15. ## 1.15.1 (2026-07-20)
  16. A Bitrix pipeline rename no longer revokes deal writes. `BITRIX_WRITE_FUNNELS`
  17. now defaults to categoryIds (`24,26,36`) instead of names: categoryIds are
  18. stable across renames, and entries may still be names. `_allowed_funnel_cats()`
  19. resolves each entry independently: an entry that cannot resolve is skipped
  20. with a warning instead of disabling all deal writes, and it only errors if
  21. none resolve. (Funnel 24, then "Partner Outreach", had been renamed to
  22. "Partner Tier Upgrade", which broke every deal write.)
  23. ## 1.15.0 (2026-07-20)
  24. Packaging: the `.mcpb` now uses the MCPB uv runtime (`server.type` "uv",
  25. manifest 0.4) instead of bundling per-platform native wheels for one pinned
  26. Python. Dependencies live in `mcpb/pyproject.toml` and are resolved on the
  27. user's machine by uv, which also provisions a compatible Python. The bundle is
  28. Python-version-agnostic (>=3.10, no cp312 ABI lock) and no longer depends on
  29. the user's system `python` being present or on PATH, which fixes the Windows
  30. "Server disconnected" failure (Store stub, wrong-version python, ABI mismatch).
  31. One universal bundle for macOS, Windows and Linux; `build.sh` no longer fetches
  32. wheels. Server logic is unchanged.
  33. ## 1.14.2 (2026-07-09)
  34. The write-funnel default now includes "Partner Outreach" (categoryId 24)
  35. alongside Quarterly Check-In Flow and Winback, so deal writes are permitted in
  36. that funnel out of the box, matching the deployed `BITRIX_WRITE_FUNNELS` and
  37. the `.mcpb` manifest. No effect where the variable is set explicitly.
  38. ## 1.14.1 (2026-06-30)
  39. Packaging. `BITRIX_DATA_DIR` lets logs and schema snapshots be written to a
  40. stable, writable location (default next to the server; the `.mcpb` points it
  41. at `~/.bitrix24-mcp`) so a packaged install survives updates. Ships as a
  42. single universal desktop extension carrying both the macOS and Windows native
  43. binaries: the org connector stores one versioned bundle per connector, so one
  44. `.mcpb` must serve every platform.
  45. ## 1.14.0 (2026-06-30)
  46. Deploy hardening and expansion, verified against the live REST docs via the
  47. b24-dev-mcp documentation server.
  48. - Security: tool-call logging redacts customer names as well as email and
  49. phone by default (`BITRIX_LOG_ARGS=redact|full|off`), and `calls.jsonl` is
  50. size-capped and rotated. Untrusted CRM free text (record fields, timeline
  51. bodies, website-chat messages) is wrapped in explicit "untrusted data"
  52. fences before it reaches the model. Record IDs are validated as numeric at
  53. tool entry.
  54. - Efficiency: one shared `httpx.AsyncClient` (connection pooling) instead of
  55. one per call. New `bitrix_batch()` wraps `rest.batch` (up to 50 commands)
  56. and powers `pipeline_summary` (N stage counts in one call), `search_crm` and
  57. bulk user-name resolution. Duplicate field formatters merged.
  58. - New reads: `get_chat_transcript` (`imopenlines.crm.chat.get` then
  59. `im.dialog.messages.get`) surfaces website-chat conversations bound to a
  60. lead, deal, contact or company, and `get_timeline` gains a Website chats
  61. section. `get_call_recording` exposes the telephony recording URL and file;
  62. `transcribe_call` (opt-in, local mlx-whisper) sits behind
  63. `BITRIX_TRANSCRIBE`. `get_record` and `get_products` gain an Order summary
  64. block (order id, invoice, money totals, partner tier).
  65. - New writes (gated by `BITRIX_WRITES`): `set_lead_fields` and
  66. `set_deal_fields` set custom fields by display label; `create_contact`,
  67. `update_contact`, `create_company` and `update_company` are gated
  68. additionally by `BITRIX_WRITE_PARTIES` and dup-checked via
  69. `crm.duplicate.findbycomm` before create.
  70. - Bitrix CoPilot output and transcripts are not REST-readable, and a call's
  71. `TRANSCRIPT_ID` has no getter, so CoPilot-style value comes from the model
  72. summarizing the data these tools expose, not from reading CoPilot itself.
  73. ## 1.13.1 (2026-06-12)
  74. `list_records` with a scoped pipeline no longer builds a cross-funnel stage
  75. filter (it shows the whole funnel unless a stage is given); item extraction
  76. tolerates list- or dict-shaped results.
  77. ## 1.13 (2026-06-12)
  78. Deal writes, locked to `BITRIX_WRITE_FUNNELS` (default "Quarterly Check-In
  79. Flow,Winback,Partner Outreach"). Every write verifies the deal's categoryId is
  80. in that set and refuses otherwise; `create_deal` only creates into those
  81. funnels. The tools map to the New-Deal form: `set_deal_stage`,
  82. `set_deal_title`, `link_deal_contact`, `link_deal_company`,
  83. `add_deal_comment`, `assign_deal`, `create_deal`. Contact and company links
  84. resolve an existing record by email, phone or name (no new records are
  85. created). Gated by `BITRIX_WRITES`.
  86. ## 1.12 (2026-06-12)
  87. `pipeline_summary` and `list_records` accept a `pipeline` (deal funnel name or
  88. categoryId), which scopes deals to that funnel's category and its
  89. `DEAL_STAGE_<cat>` stages, so a named customer-success funnel (for example
  90. Quarterly Check-In Flow) gets correct per-stage counts and record lists. The
  91. funnel is resolved by fuzzy name match via `crm.category.list` (cached).
  92. ## 1.11 (2026-06-12)
  93. `list_pipelines` (read-only) enumerates deal funnels via `crm.category.list`
  94. (each with its stages from `crm.status.list`) and smart processes via
  95. `crm.type.list`: the discovery step before scoping `pipeline_summary` or
  96. `list_records` to a named non-default pipeline.
  97. ## 1.10 (2026-06-05)
  98. `get_call_history` (read-only) wraps `voximplant.statistic.get` to surface,
  99. per call: localized start time, direction, number, duration, the bound CRM
  100. entity (type and id; calls bind to whatever record, often a contact), whether
  101. a recording URL is present, and Bitrix's own transcript id and pending flag.
  102. Requires the telephony scope on the webhook. This is the probe that decides
  103. the call-transcription architecture (Bitrix transcript or local mlx-whisper)
  104. and the read foundation the transcription work reuses.
  105. ## 1.9 (2026-06-05)
  106. First writes. Two lead-only write tools: `add_lead_comment`
  107. (`crm.timeline.comment.add`) and `rename_lead` (`crm.item.update` title). Both
  108. hardcode the lead entity; neither can touch deals, contacts or companies.
  109. Writes are gated by `BITRIX_WRITES` (default on; set "off" to disable).
  110. `rename_lead` refuses to overwrite a title that looks human-authored unless
  111. `overwrite_named=True`; all write text is sanitized (control characters
  112. stripped, length capped). Every write is logged to `calls.jsonl` with before
  113. and after. `get_timeline` gains `full_text` to return untruncated activity
  114. bodies for the summarize-to-comment workflow. Call transcription is left out
  115. on purpose: CoPilot transcripts are not REST-reachable, and raw audio needs the
  116. telephony scope plus transcription, a separate project.
  117. ## 1.8.3 (2026-06-05)
  118. Packaging: `tzdata` added to requirements (Windows has no system timezone
  119. database and zoneinfo needs one there), and a missing timezone database no
  120. longer stops the server from starting. No tool changes.
  121. ## 1.8.2 (2026-06-05)
  122. Security hardening: transport-level httpx exceptions are caught, retried and
  123. re-raised as `BitrixError` with the webhook URL redacted (previously they
  124. could propagate raw); pagination and product-row numeric parsing tolerate
  125. malformed API values.
  126. ## 1.8.1 (2026-06-05)
  127. Stage history field names vary by entity (leads report `STATUS_ID`, deals
  128. `STAGE_ID`); both are now read.
  129. ## 1.8 (2026-06-05)
  130. Reads expansion. `get_products` (`crm.item.productrow.list`) answers "what did
  131. they order"; `get_stage_history` (`crm.stagehistory.list`) shows stage
  132. movement with time in stage; `get_timeline` includes staff notes
  133. (`crm.timeline.comment.list`) with author names; user IDs in `get_record` and
  134. `list_records` resolve to names (cached); boolean field filters work via a
  135. client-side scan (Bitrix ignores them server-side; the scan is capped at 200
  136. records and labeled as such).
  137. ## 1.7 (2026-06-05)
  138. Timezone-correct dates. `list_records` accepts `created_on`, `created_from`,
  139. `created_to` and `tz`; day windows are computed in the local zone
  140. (`BITRIX_LOCAL_TZ`, default America/Chicago) and passed to Bitrix as
  141. offset-aware ISO 8601 bounds on `createdTime`. Date-filtered queries paginate
  142. past the 50-row cap. Timestamps in `get_record` are displayed in local time
  143. with the raw offset string preserved; list and timeline lines show local time.
  144. zoneinfo throughout, no fixed offsets, DST-safe.
  145. ## 1.6.3 (2026-06-05)
  146. Security and ship pass: logs live inside the repo folder (they had been
  147. written one level up, a leftover of an old `src/` layout); emails and phone
  148. numbers are masked in `calls.jsonl` entries; the `search_crm` limit is capped
  149. at 50; dependency versions are bounded.
  150. ## 1.6.2 (2026-06-04)
  151. Boolean `UF_*` filters are refused with an explanation: live testing showed
  152. `crm.item.list` silently ignores them and returns the unfiltered set.
  153. Enum, string and date filters verified working.
  154. ## 1.6.1 (2026-06-04)
  155. `crm.item.list` filters on `UF_*` fields require `useOriginalUfNames=Y`, now
  156. sent by `list_records`. Bitrix HTTP 4xx error bodies are parsed into
  157. `BitrixError` messages instead of surfacing raw httpx exceptions, which
  158. embedded the webhook URL, token included, in the error text shown to the
  159. client.
  160. ## 1.6 (2026-06-04)
  161. `find_field` (search field definitions by label or ID fragment across all
  162. entity types); `list_records` accepts `field`/`value` to filter on any field
  163. by its display label, with enum option labels and yes/no booleans translated
  164. automatically; the field schema is snapshotted to `./schema/` (one dated JSON
  165. file per entity per day) so form-builder drift is diffable over time.
  166. ## 1.5 (2026-06-04)
  167. `get_fields`: the full field schema per entity type via `crm.item.fields`
  168. (cached). `get_record` labels custom `UF_*` fields with their configured
  169. display names and translates enumeration value IDs into their display labels.
  170. ## 1.4 (2026-06-04)
  171. Assignee support. `pipeline_summary` accepts `assigned_to` ('me', a name, or
  172. a numeric user ID, resolved via `user.current`, `user.search` or `user.get`);
  173. the new `list_records` tool lists records filtered by assignee and/or stage.
  174. User lookups are cached per process.
  175. ## 1.3 (2026-06-04)
  176. `pipeline_summary`: per-stage counts for leads and deals with human-readable
  177. stage names via `crm.status.list` (cached per process). Counts come from the
  178. `crm.item.list` response envelope's `total`, so they are exact regardless of
  179. page size.
  180. ## 1.2 (2026-06-04)
  181. Leads (entityTypeId 1) added to all three CRM tools. `search_crm` 'all' covers
  182. lead, contact, company and deal; `findbycomm` covers leads. Section headers
  183. properly pluralized.
  184. ## 1.1 (2026-06-04)
  185. CRM reads migrated from the legacy `crm.{entity}.list/get` family (development
  186. halted by Bitrix) to the universal `crm.item.*` API. Email and phone lookup
  187. uses `crm.duplicate.findbycomm`. Verified against https://apidocs.bitrix24.com
  188. (crm-item-list, crm-item-get, crm-duplicate-find-by-comm). Tool contracts
  189. unchanged.
  190. ## 1.0
  191. The core read tools: `search_crm`, `get_record`, `get_timeline` and
  192. `list_tasks`, over an incoming webhook (`BITRIX_WEBHOOK_URL`) and stdio. Tool
  193. names are semantic rather than Bitrix-specific so the interface survives a
  194. future CRM migration: the implementation behind them is what gets swapped, not
  195. the contracts. Every call is logged to `logs/calls.jsonl` for migration
  196. evaluation.