Skip to content

feat: excludeDrafts param for getThreads (v2.2.1) - #2

Merged
zackkatz merged 15 commits into
mainfrom
develop
Mar 3, 2026
Merged

feat: excludeDrafts param for getThreads (v2.2.1)#2
zackkatz merged 15 commits into
mainfrom
develop

Conversation

@zackkatz

@zackkatz zackkatz commented Mar 3, 2026

Copy link
Copy Markdown
Member

Summary

  • Add excludeDrafts parameter to getThreads (default: true) — filters AI-generated drafts (source.type: "support-agent-ai") and unsent drafts (state: "draft") from results
  • Add support-agent-ai filter to buildTranscript (inline transcripts via searchConversations)
  • Include draftsExcluded: true flag in all three output formats (transcript, verbose, slim)
  • Set excludeDrafts: false to include all threads including AI drafts

Why: Help Scout assigns AI drafts to the mailbox owner's name in createdBy, causing AI agents to falsely attribute them as real staff replies.

Test plan

  • Verify getThreads with default params excludes AI drafts and unsent drafts
  • Verify getThreads with excludeDrafts: false returns all threads
  • Verify transcript format excludes drafts
  • Verify inline transcripts via searchConversations exclude drafts
  • Build succeeds: npm run build

Summary by CodeRabbit

  • New Features

    • Conversation management: create, retrieve, and update conversations (assignees, tags, custom fields).
    • Reply creation: draft or published replies with HTML formatting and configurable spacing; option to exclude AI drafts from thread results.
    • New tools/endpoints to manage replies and conversations.
  • Documentation

    • Updated README with examples and new Reply/Conversation sections.
    • Added comprehensive Help Scout API reference.
  • Chores

    • Package version bump and added multipart/form-data support dependency.

- CreateReplyInputSchema with Zod validation (conversationId, text, customer, draft, cc/bcc, status)
- replySpacing (relaxed/compact) and allowSendReply config options
- postWithResponse method on HelpScoutClient to capture Resource-Id header
- Updated .env.example with HELPSCOUT_REPLY_SPACING and HELPSCOUT_ALLOW_SEND_REPLY
- Draft by default; HELPSCOUT_ALLOW_SEND_REPLY=true required to send
- formatReplyHtml transforms HTML for Help Scout's native editor:
  - <p> → <br><br>, <pre> → <div> with newlines as <br>
  - Inline <code> gets class="inline-code" (existing classes preserved)
  - Block element spacing normalized (relaxed/compact via env var)
- API constraint validation for conversationId, text, customer
14 new tests covering:
- Draft/published reply creation and safety controls
- Optional fields (cc, bcc, status, user, assignTo)
- API constraint validation (invalid ID, missing fields)
- HTML formatting: <p> conversion, <code> class injection,
  <pre> → <div>, list/blockquote spacing (relaxed + compact)
Complete conversation lifecycle: create tickets, fetch by ID, and update
status/assignee/tags/custom fields. Uses correct Help Scout API formats:
- JSONPatch for PATCH /conversations/{id}
- PUT for /conversations/{id}/tags and /conversations/{id}/fields
- Resource-Id header extraction for POST responses
- Zod validation, slim/verbose responses, cache invalidation
15 new tests covering getConversation, createConversation, and
updateConversation including JSONPatch format, PUT for tags/fields,
Resource-Id header handling, and input validation via api-constraints.
- Add getConversation, createConversation, updateConversation to README
  tool table with usage examples
- Add 3 tools to MCPB manifest.json
- Copy Help Scout API reference from MonoKit with corrections:
  Update Conversation uses JSONPatch (not flat JSON), tags via PUT,
  custom fields via PUT, embed only supports 'threads'
createDocsArticleAsset, uploadDocsArticle, and createDocsSettingsAsset
were sending JSON instead of multipart/form-data, which the Help Scout
Docs API requires for file uploads. Added articleId as a required param
for article assets. Added postFormData method to the docs client. Added
form-data as a direct dependency.
LLMs typically output \n instead of HTML tags. Strip newlines after
block-level closing tags (formatting whitespace), convert double \n
to paragraph breaks, and single \n to <br>.
Why: Help Scout API returns article text wrapped in <![CDATA[...]]> which was passed through to callers, causing ]]> to appear literally at the end of article content

- Add stripCdata() helper to remove CDATA wrapper from API responses
- Apply to getDocsArticle (verbose and slim modes) and search result previews
- Does not affect text sent TO the API (create/update operations)
Why: Help Scout AI drafts show the mailbox owner's name in createdBy,
causing AI agents to falsely attribute them as real staff replies.

- Add excludeDrafts param to getThreads (default: true)
- Filter state=draft and source.type=support-agent-ai in all formats
- Add support-agent-ai filter to buildTranscript
- Include draftsExcluded flag in all output formats
- Update README with excludeDrafts documentation
@coderabbitai

coderabbitai Bot commented Mar 3, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1eba088 and 16c47fb.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (2)
  • package.json
  • src/__tests__/tools.test.ts

Walkthrough

Adds four new Help Scout tools (createReply, getConversation, createConversation, updateConversation), new input schemas and validations, client methods for POST/PATCH/PUT and multipart uploads, config flags for reply spacing and publish permission, docs updates, and expanded tests.

Changes

Cohort / File(s) Summary
Configuration & Env
/.env.example, helpscout-mcp-extension/manifest.json, src/utils/config.ts
Add HELPSCOUT_REPLY_SPACING and HELPSCOUT_ALLOW_SEND_REPLY; expose config.helpscout.replySpacing and config.helpscout.allowSendReply; manifest and user_config updated.
New Tools & Router
src/tools/index.ts
Add createReply, getConversation, createConversation, updateConversation implementations and dispatch cases; add formatReplyHtml and excludeDrafts handling for threads.
Schemas & Validation
src/schema/types.ts, src/utils/api-constraints.ts
Add CreateReply/GetConversation/CreateConversation/UpdateConversation input schemas and types; extend GetThreadsInputSchema with excludeDrafts; add validators for the new tools and guidance messages.
API Clients & Uploads
src/utils/helpscout-client.ts, src/utils/helpscout-docs-client.ts, package.json
Add postWithResponse, patch, put to HelpScoutClient; add getApiKey and postFormData (uses form-data) to Docs client; add form-data dependency.
Docs & Reference
README.md, docs/help-scout-api-reference.md
Expand README with reply/conversation examples and config notes; add large Help Scout API reference doc.
Docs Tools & Assets
src/tools/docs-tools.ts
Introduce stripCdata, change asset upload signatures to article-based and settings endpoints, switch to multipart/form-data uploads via FormData and createReadStream.
Tests & Manifest Validation
src/__tests__/tools.test.ts, src/__tests__/mcpb-validation.test.ts
Add extensive tests for new tools, HTML formatting, transcripts, and config-driven behavior; update manifest-tools count to include new tools.
Extension Manifest
helpscout-mcp-extension/manifest.json
Expose new tools and user_config fields; add server env entries for new vars; update descriptions to reflect draft/published reply behavior.

Sequence Diagram(s)

sequenceDiagram
  participant User as Client
  participant TH as ToolHandler
  participant CFG as Config
  participant HS as HelpScoutClient
  participant API as HelpScout API

  User->>TH: call createReply(args)
  TH->>CFG: read replySpacing & allowSendReply
  TH->>TH: formatReplyHtml(args.html, replySpacing)
  TH->>HS: postWithResponse("/conversations/{id}/threads", {type: "reply", ...})
  HS->>API: POST /conversations/{id}/threads
  API-->>HS: 201 Created (thread/draft id)
  HS-->>TH: {status, headers, data}
  TH->>TH: if published -> patch conversation status (guarded by allowSendReply)
  TH-->>User: return created reply metadata (draft/published)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately and clearly describes the main feature: adding an excludeDrafts parameter to the getThreads function with versioning.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch develop

Comment @coderabbitai help to get the list of available commands and usage tips.

zackkatz added 2 commits March 3, 2026 17:10
- Default excludes AI drafts (source.type: support-agent-ai) and unsent drafts (state: draft)
- excludeDrafts:false includes all threads
- Transcript format excludes drafts
- Verbose format excludes drafts
- Inline transcripts via searchConversations exclude drafts
@zackkatz
zackkatz merged commit d4fa5fb into main Mar 3, 2026
12 checks passed
jgalea pushed a commit to jgalea/help-scout-mcp that referenced this pull request Apr 25, 2026
feat: excludeDrafts param for getThreads (v2.2.1)
@coderabbitai coderabbitai Bot mentioned this pull request Jun 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant