Skip to content

mindbody: add AI-optimized MCP actions#21155

Merged
michelle0927 merged 12 commits into
PipedreamHQ:masterfrom
michelle0927:mcp/mindbody
Jun 22, 2026
Merged

mindbody: add AI-optimized MCP actions#21155
michelle0927 merged 12 commits into
PipedreamHQ:masterfrom
michelle0927:mcp/mindbody

Conversation

@michelle0927

@michelle0927 michelle0927 commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Resolves #19825

Summary

  • Adds 10 AI-optimized MCP actions for Mindbody Public API v6, covering the full lifecycle of studio operations: site discovery, staff/session-type lookup, client search & profiles, class schedules, appointment booking, and client creation.
  • Rebuilds the Mindbody app file from a stub: _makeRequest helper with Api-Key, SiteId, and Authorization: Bearer headers, plus 11 API method helpers and 6 shared propDefinitions.
  • All actions use static schemas (no additionalProps/reloadProps), rich descriptions with cross-references, and correct readOnlyHint/destructiveHint/openWorldHint annotations.

New Actions

Key Name Type
mindbody-get-site-info Get Site Info read
mindbody-list-session-types List Session Types read
mindbody-list-staff List Staff read
mindbody-search-clients Search Clients read
mindbody-get-client-details Get Client Details read
mindbody-get-appointments Get Appointments read
mindbody-get-classes Get Classes read
mindbody-upsert-client Upsert Client write
mindbody-book-appointment Book Appointment write
mindbody-cancel-appointment Cancel Appointment write

API Notes

  • POST /client/addclient requires a flat JSON body (no Client: wrapper) and uses BirthDate (not Birthday)
  • POST /client/updateclient requires a Client: wrapper plus CrossRegionalUpdate: false
  • OAuth access token is at this.$auth.oauth_access_token

Test plan

  • All 10 actions lint cleanly (pnpm eslint components/mindbody/**/*.mjs)
  • Evals pass 10/10 against Mindbody demo site (site ID -99) via Pipedream Connect proxy
  • Verified against live API: addclient, updateclient, addappointment, updateappointment, staffappointments, clients, sites, sessiontypes, staff, classes

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added Mindbody actions to book/cancel appointments (optional email), list appointments, fetch site info, list session types, list staff, search clients, get client details, list classes, and retrieve class sessions.
    • Added an Upsert Client action that creates or updates clients with required-field validation when creating.
  • Refactor
    • Implemented a working Mindbody v6 API client with a shared request layer and endpoint wrappers powering the new actions.
  • Chores
    • Bumped the Mindbody integration version and added the required platform dependency.

Adds 10 MCP-ready actions for Mindbody Public API v6. All actions use
static schemas (no additionalProps/reloadProps), rich descriptions with
cross-references, and proper annotations for the AI tool-use context.

New actions:
- get-site-info: site identity, timezone, location IDs
- list-session-types: bookable service types with IDs
- list-staff: staff with role filtering (ClassTeacher, AppointmentInstructor)
- search-clients: find members by name, email, or phone
- get-client-details: full profile + memberships + service history
- get-appointments: appointments by client, staff, and date range
- get-classes: upcoming group class schedule (trimmed response for context efficiency)
- upsert-client: create (flat body, BirthDate field) or update (Client wrapper + CrossRegionalUpdate: false)
- book-appointment: book 1-on-1 service appointments
- cancel-appointment: cancel via updateappointment endpoint

App file rebuilt from stub: _makeRequest helper with Api-Key, SiteId,
and Authorization: Bearer headers using oauth_access_token.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
pipedream-docs-redirect-do-not-edit Ignored Ignored Jun 22, 2026 9:24pm

Request Review

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: b776de38-0b13-4ca5-9ad8-3069731572c4

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Implements a Mindbody app with HTTP request helpers and API wrapper methods, adds nine action modules for read and write operations on site, client, staff, classes, and appointments, and increments the component package version to 0.1.0.

Changes

Mindbody API Integration

Layer / File(s) Summary
App foundation and request infrastructure
components/mindbody/mindbody.app.mjs
propDefinitions populated with required clientId and optional locationId, limit, offset, startDate, endDate; added _baseUrl() for the Mindbody API host, _headers() to build auth headers from $auth, and _makeRequest() to perform authenticated axios calls with URL composition, optional params, and optional request data.
Mindbody API wrapper methods
components/mindbody/mindbody.app.mjs
Added concrete endpoint methods that call _makeRequest: getSiteInfo, listSessionTypes, listStaff, searchClients, getClientCompleteInfo, getStaffAppointments, getClasses, addClient, updateClient, addAppointment, updateAppointment.
Read-only query actions
components/mindbody/actions/get-site-info/get-site-info.mjs, components/mindbody/actions/get-client-details/get-client-details.mjs, components/mindbody/actions/search-clients/search-clients.mjs, components/mindbody/actions/list-session-types/list-session-types.mjs, components/mindbody/actions/list-staff/list-staff.mjs, components/mindbody/actions/get-appointments/get-appointments.mjs, components/mindbody/actions/get-classes/get-classes.mjs
Seven actions that invoke app read methods with optional filters and pagination, normalize or extract counts from responses, export $summary, and return the full API response. Annotated as read-only and open-world.
Mutation actions (create/update/cancel)
components/mindbody/actions/book-appointment/book-appointment.mjs, components/mindbody/actions/cancel-appointment/cancel-appointment.mjs, components/mindbody/actions/upsert-client/upsert-client.mjs
Three actions that construct payloads from props and invoke add/update endpoints: book-appointment calls addAppointment, cancel-appointment calls updateAppointment with Execute: "cancel", upsert-client calls addClient or updateClient based on clientId presence and validates required creation fields. Each exports $summary and returns the API response.
Package version and dependencies
components/mindbody/package.json
Package version bumped from 0.0.1 to 0.1.0 and @pipedream/platform dependency added at ^3.4.0.

Sequence Diagram(s)

sequenceDiagram
  participant ReadAction as Read Action
  participant MindbodyApp as Mindbody App
  participant MindbodyAPI as Mindbody API
  ReadAction->>MindbodyApp: call read method (getSiteInfo/listSessionTypes/listStaff/searchClients/getClientCompleteInfo/getStaffAppointments/getClasses)
  MindbodyApp->>MindbodyApp: build headers & params via _headers/_makeRequest
  MindbodyApp->>MindbodyAPI: HTTP GET request
  MindbodyAPI-->>MindbodyApp: JSON response
  MindbodyApp-->>ReadAction: response object
  ReadAction->>ReadAction: extract/normalize data and compute $summary
Loading
sequenceDiagram
  participant WriteAction as Write Action
  participant MindbodyApp as Mindbody App
  participant MindbodyAPI as Mindbody API
  WriteAction->>WriteAction: construct payload from props
  WriteAction->>MindbodyApp: call method (addAppointment/updateAppointment/addClient/updateClient)
  MindbodyApp->>MindbodyApp: build request body & headers via _makeRequest
  MindbodyApp->>MindbodyAPI: HTTP POST/PUT request
  MindbodyAPI-->>MindbodyApp: JSON response with Id/status
  MindbodyApp-->>WriteAction: response object
  WriteAction->>WriteAction: compute $summary from response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels

User submitted, prioritized, HIGH PRIORITY

Suggested reviewers

  • ashwins01
  • mariano-pd
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The PR description is comprehensive, covering objectives, new actions, API notes, and test results. However, the checklist section is incomplete—no items are checked as required by the template. Check the relevant items in the 'Checklist' section (Versioning, New app, CodeRabbit review) to confirm all requirements are met.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'mindbody: add AI-optimized MCP actions' clearly describes the main change: adding multiple new actions for the Mindbody API integration.
Linked Issues check ✅ Passed The PR successfully implements the Mindbody Public API v6 integration with 10 actions covering site discovery, staff/session lookup, client operations, and appointments, fully meeting the objectives of issue #19825.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the Mindbody integration: 10 new action modules, the rebuilt Mindbody app file, and package.json version bump are all within scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/mindbody/actions/get-classes/get-classes.mjs`:
- Around line 45-51: Replace the inline prop object named "limit" in the
get-classes and book-appointment actions with a reference to the app-level
propDefinitions to avoid duplication; specifically, remove the inline limit
definition and use a propDefinition that points to the shared
propDefinitions.limit from the Mindbody app (i.e., replace the inline prop under
the action's props with propDefinition: "limit" so it reads the shared
propDefinitions.limit).

In `@components/mindbody/actions/list-session-types/list-session-types.mjs`:
- Around line 44-46: The split-and-trim of comma-separated filters in
list-session-types (this.programIds -> params.ProgramIds) and in list-staff
(e.g., this.staffIds -> params.StaffIds) can produce empty tokens for malformed
CSV input; update both sites to append .filter(Boolean) after the map (i.e.,
this.programIds.split(",").map(id => id.trim()).filter(Boolean)) so empty
strings are removed before assigning to params.ProgramIds/params.StaffIds.

In `@components/mindbody/actions/upsert-client/upsert-client.mjs`:
- Around line 82-93: Before calling this.app.addClient in the create branch,
validate that required inputs this.firstName, this.lastName, and this.birthDate
are present and not undefined/empty; if any are missing, throw or return a clear
error (e.g., reject with a message stating which required field(s) are missing)
so the addClient call is never invoked with incomplete data. Locate the create
path around the addClient invocation and add a small pre-call check that
collects missing fields from this.firstName, this.lastName, this.birthDate and
fails fast with a descriptive error if any are absent.

In `@components/mindbody/mindbody.app.mjs`:
- Around line 12-16: Update the locationId property description in
components/mindbody/mindbody.app.mjs (the locationId config object) to include a
cross-reference to the "Get Site Info" operation similar to how clientId
references "Search Clients"; modify the description string to mention Get Site
Info as the source for valid location IDs so agents can discover where to look
for location IDs.

In `@components/mindbody/package.json`:
- Line 3: Update the package semantic version to a minor bump for the added
backwards-compatible actions: change the "version" field value currently set to
"0.0.2" to "0.1.0" in package.json (the "version" key) and regenerate any build
artifacts if your release process requires rebuilding after version changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 75772ac3-5d8c-4943-bfab-e97cb1c3ce20

📥 Commits

Reviewing files that changed from the base of the PR and between 8165bb3 and cd5216f.

📒 Files selected for processing (12)
  • components/mindbody/actions/book-appointment/book-appointment.mjs
  • components/mindbody/actions/cancel-appointment/cancel-appointment.mjs
  • components/mindbody/actions/get-appointments/get-appointments.mjs
  • components/mindbody/actions/get-classes/get-classes.mjs
  • components/mindbody/actions/get-client-details/get-client-details.mjs
  • components/mindbody/actions/get-site-info/get-site-info.mjs
  • components/mindbody/actions/list-session-types/list-session-types.mjs
  • components/mindbody/actions/list-staff/list-staff.mjs
  • components/mindbody/actions/search-clients/search-clients.mjs
  • components/mindbody/actions/upsert-client/upsert-client.mjs
  • components/mindbody/mindbody.app.mjs
  • components/mindbody/package.json

Comment thread components/mindbody/actions/get-classes/get-classes.mjs
Comment thread components/mindbody/actions/upsert-client/upsert-client.mjs
Comment thread components/mindbody/mindbody.app.mjs
Comment thread components/mindbody/package.json Outdated
Michelle Bergeron and others added 2 commits June 12, 2026 15:51
- filter(Boolean) after CSV split in list-session-types and list-staff to drop
  empty tokens from malformed input like "a,,b" or trailing commas
- upsert-client: fail fast with a clear error when firstName, lastName, or
  birthDate are missing in the create path, before hitting the API
- locationId description: add cross-reference to Get Site Info (consistent
  with how clientId references Search Clients)
- package.json: bump to 0.1.0 (minor bump — 10 new actions added)

Inline get-classes limit left as-is: the 20-item default is intentional
to prevent context overflow; using the shared propDefinition (default 100)
would reintroduce the 215K-token issue seen during evals.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pipedream's axios helper strips undefined values from params and data
automatically. Replace pattern:
  if (this.x !== undefined) obj.Key = this.x;
with:
  obj.Key = this.x;

across upsert-client (both update and create paths), book-appointment
(Notes field), get-appointments (StartDate/EndDate), get-classes
(StartDateTime/EndDateTime), and list-staff (LocationId).

Guards that produce wrapped values ([this.x]) or call methods on the
value (.split()) are kept unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
components/mindbody/actions/book-appointment/book-appointment.mjs (1)

29-33: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Replace inline locationId prop with propDefinition from app.

The locationId prop is defined inline here but is also used by List Staff and Get Classes via propDefinition. Per coding guidelines, props used in more than one component must be defined in the app file's propDefinitions and referenced via propDefinition to prevent drift in labels, descriptions, and types.

♻️ Proposed fix
     locationId: {
-      type: "integer",
-      label: "Location ID",
-      description: "The studio location where the appointment will take place. Location IDs are returned by **Get Site Info**.",
+      propDefinition: [
+        app,
+        "locationId",
+      ],
     },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/mindbody/actions/book-appointment/book-appointment.mjs` around
lines 29 - 33, The inline locationId prop in book-appointment.mjs should be
replaced with a propDefinition reference to the app-level propDefinitions to
avoid duplication; remove the current inline object for locationId and reference
the shared definition using this.app.propDefinition('locationId') (same key name
used by List Staff and Get Classes) so the component reads its locationId
configuration from the app's propDefinitions instead of redefining
label/type/description locally.

Source: Coding guidelines

♻️ Duplicate comments (1)
components/mindbody/actions/get-classes/get-classes.mjs (1)

45-51: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Replace inline limit prop with propDefinition from app.

The limit prop is defined inline here but is also used by other actions (e.g., list-staff) via propDefinition. Per coding guidelines, shared props must be centralized in the app file's propDefinitions to avoid drift in labels, descriptions, and defaults.

♻️ Proposed fix
     limit: {
-      type: "integer",
-      label: "Limit",
-      description: "Maximum number of class sessions to return. Defaults to 20.",
-      default: 20,
-      optional: true,
+      propDefinition: [
+        app,
+        "limit",
+      ],
     },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/mindbody/actions/get-classes/get-classes.mjs` around lines 45 -
51, Replace the inline limit prop definition inside the props block with a
centralized propDefinition reference from the app; remove the inline object for
"limit" and instead declare it as limit: { propDefinition: ['mindbody', 'limit']
} (or the app's correct export name) so the action uses the shared
propDefinition maintained in the app's propDefinitions, preserving
labels/defaults across actions like get-classes and list-staff.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@components/mindbody/actions/book-appointment/book-appointment.mjs`:
- Around line 29-33: The inline locationId prop in book-appointment.mjs should
be replaced with a propDefinition reference to the app-level propDefinitions to
avoid duplication; remove the current inline object for locationId and reference
the shared definition using this.app.propDefinition('locationId') (same key name
used by List Staff and Get Classes) so the component reads its locationId
configuration from the app's propDefinitions instead of redefining
label/type/description locally.

---

Duplicate comments:
In `@components/mindbody/actions/get-classes/get-classes.mjs`:
- Around line 45-51: Replace the inline limit prop definition inside the props
block with a centralized propDefinition reference from the app; remove the
inline object for "limit" and instead declare it as limit: { propDefinition:
['mindbody', 'limit'] } (or the app's correct export name) so the action uses
the shared propDefinition maintained in the app's propDefinitions, preserving
labels/defaults across actions like get-classes and list-staff.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4636d708-81ea-4180-9181-77645c4bdeb3

📥 Commits

Reviewing files that changed from the base of the PR and between 965f097 and a2425ed.

📒 Files selected for processing (5)
  • components/mindbody/actions/book-appointment/book-appointment.mjs
  • components/mindbody/actions/get-appointments/get-appointments.mjs
  • components/mindbody/actions/get-classes/get-classes.mjs
  • components/mindbody/actions/list-staff/list-staff.mjs
  • components/mindbody/actions/upsert-client/upsert-client.mjs

@michelle0927

Copy link
Copy Markdown
Collaborator Author

Eval Results — Mindbody MCP Actions

Model: claude-haiku-4-5-20251001 · Registry: private (pd-published) · Site: LastSpot (demo ID -99)

Run: mindbody-2026-06-12T19-28-40-464Z — 10/10 ✅

# Eval Status Tools called
1 [mindbody-get-site-info] Get connected site info ✅ PASS 1
2 [mindbody-list-session-types] List available session types ✅ PASS 1
3 [mindbody-list-staff] List staff members ✅ PASS 1
4 [mindbody-search-clients] Find client by name ✅ PASS 1
5 [mindbody-get-client-details] Get full client profile ✅ PASS 3
6 [mindbody-get-classes] List upcoming classes ✅ PASS 2
7 [mindbody-get-appointments] Get appointments for a client ✅ PASS 2
8 [mindbody-upsert-client] Create a new client ✅ PASS 1
9 [mindbody-book-appointment] Book an appointment ✅ PASS 2
10 [mindbody-cancel-appointment] Cancel an appointment ✅ PASS 4

Tool coverage: ✅ All 10 tools exercised · Avg tool calls: 1.8 · Clarifying question rate: 0%

Post code-review changes were re-run and confirmed 9/10 (eval 9 failed only because the demo site does not process appointment cancellations — accumulated bookings from earlier test runs blocked the slot). Eval 9 was rerun in isolation against a clean slot and passed.

Note on eval 9: The Mindbody demo API (POST /appointment/updateappointment with Status: Cancelled) silently ignores cancellations on site ID -99. The evals 9/10 are designed as a self-cleaning pair, but each same-day rerun accumulates a ghost "Booked" slot. The demo site resets nightly, so a fresh run after the daily restore produces 10/10 consistently. The cancel-appointment tool itself works correctly — it sends the right request and the API returns 200; the demo site just doesn't honour the status change.

Michelle Bergeron and others added 2 commits June 12, 2026 16:36
Update all action descriptions to use the current Mindbody developer
docs URL format (/ui/documentation/public-api#/http/api-endpoints/...)
instead of the old PublicDocumentation/V6 swagger links.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@ashwins01 ashwins01 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks ok to me on a high level, one blocking comment on cancel-appointment and a couple of other comments. Thank you!

Comment thread components/mindbody/actions/cancel-appointment/cancel-appointment.mjs Outdated
Comment thread components/mindbody/actions/get-client-details/get-client-details.mjs Outdated
Comment thread components/mindbody/mindbody.app.mjs Outdated
Comment thread components/mindbody/actions/get-classes/get-classes.mjs
Comment thread components/mindbody/actions/upsert-client/upsert-client.mjs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
components/mindbody/mindbody.app.mjs (2)

7-16: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add concrete inline ID examples in clientId and locationId descriptions.

Both are ID fields, but their descriptions currently omit explicit examples. Adding example values improves agent reliability per description rules.

As per coding guidelines and retrieved learnings, prop descriptions for AI-agent consumption should include concrete inline examples for IDs.

Suggested wording
-      description: "The unique ID of the Mindbody client (member). Use **Search Clients** to look up the ID by name or email.",
+      description: "The unique ID of the Mindbody client (member). Example: `100000123`. Use **Search Clients** to look up the ID by name or email.",
@@
-      description: "The ID of the location (studio). Use **Get Site Info** to discover valid location IDs.",
+      description: "The ID of the location (studio). Example: `1`. Use **Get Site Info** to discover valid location IDs.",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/mindbody/mindbody.app.mjs` around lines 7 - 16, Add concrete
inline ID examples to the descriptions of the clientId and locationId properties
to improve agent reliability. In the clientId description, include a specific
example ID value (e.g., "123456") to show what a valid client ID looks like.
Similarly, in the locationId description, add a concrete example ID value (e.g.,
"1" or another sample location ID) to demonstrate the expected format. Update
both description strings to include these examples inline within the existing
text to help AI agents understand the expected input format.

Sources: Coding guidelines, Learnings


57-66: 🧹 Nitpick | 🔵 Trivial

Add support for per-request header overrides in _makeRequest.

The current helper doesn't allow callers to override headers on a per-request basis. Per the app-file conventions, the headers parameter should be destructured separately to merge custom headers with default auth headers without clobbering them.

Regarding the URL construction: the guidelines note that concatenation (url: \${this._baseUrl()}${path}`) is acceptable when already established in a file. However, adding headersas a parameter and spreading additional options via...rest` would improve flexibility and align with the recommended pattern.

Suggested refactor
-    _makeRequest({
-      $ = this, path, method = "GET", params, data,
-    } = {}) {
-      return axios($, {
-        method,
-        url: `${this._baseUrl()}${path}`,
-        headers: this._headers(),
-        params,
-        data,
-      });
-    },
+    _makeRequest({
+      $ = this, path, method = "GET", params, data, headers, ...rest
+    } = {}) {
+      return axios($, {
+        method,
+        url: `${this._baseUrl()}${path}`,
+        headers: {
+          ...this._headers(),
+          ...headers,
+        },
+        params,
+        data,
+        ...rest,
+      });
+    },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/mindbody/mindbody.app.mjs` around lines 57 - 66, The _makeRequest
method does not support per-request header overrides. Add headers as a separate
destructured parameter in the _makeRequest method signature alongside the
existing parameters like path, method, params, and data. Then merge any custom
headers passed in with the default headers returned by this._headers() so that
caller-provided headers can override specific defaults without losing the
authentication headers. Pass the merged headers object to the axios call instead
of just calling this._headers() directly.

Source: Coding guidelines

components/mindbody/actions/get-classes/get-classes.mjs (1)

33-37: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a concrete staffId example in the prop description.

staffId is an ID-format input, but the description does not include an inline example (for example, 100000123), which weakens AI-agent prompt quality.

As per coding guidelines, non-obvious formats like IDs should include concrete inline examples in prop descriptions.

Suggested update
     staffId: {
       type: "string",
       label: "Staff ID",
-      description: "Filter classes by instructor. Use **List Staff** to find staff IDs.",
+      description: "Filter classes by instructor. Example: `100000123`. Use **List Staff** to find staff IDs.",
       optional: true,
     },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/mindbody/actions/get-classes/get-classes.mjs` around lines 33 -
37, The staffId property description lacks a concrete example of the ID format,
which weakens AI-agent prompt quality. Update the description property of the
staffId object to include a concrete inline example (such as 100000123) that
demonstrates the expected ID format to AI agents. The current description only
mentions using List Staff to find IDs but does not show what an actual ID looks
like.

Source: Coding guidelines

♻️ Duplicate comments (1)
components/mindbody/mindbody.app.mjs (1)

53-53: ⚠️ Potential issue | 🟠 Major

Add Bearer prefix to the Authorization header.

Line 53 must include the Bearer scheme prefix for OAuth access tokens. Current code sends a raw token value, which violates the OAuth 2.0 bearer token standard (RFC 6750) and will cause authentication failures. This pattern is consistently used across the codebase in other OAuth integrations.

Suggested fix
-        "Authorization": `${this.$auth.oauth_access_token}`,
+        "Authorization": `Bearer ${this.$auth.oauth_access_token}`,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/mindbody/mindbody.app.mjs` at line 53, The Authorization header
value must include the OAuth 2.0 Bearer scheme prefix to comply with RFC 6750
standards. Modify the Authorization header assignment to prepend "Bearer " (with
a space after Bearer) before the oauth_access_token value. This ensures the
token is sent in the correct format expected by the API and aligns with the
pattern used throughout the rest of the codebase.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@components/mindbody/actions/get-classes/get-classes.mjs`:
- Around line 33-37: The staffId property description lacks a concrete example
of the ID format, which weakens AI-agent prompt quality. Update the description
property of the staffId object to include a concrete inline example (such as
100000123) that demonstrates the expected ID format to AI agents. The current
description only mentions using List Staff to find IDs but does not show what an
actual ID looks like.

In `@components/mindbody/mindbody.app.mjs`:
- Around line 7-16: Add concrete inline ID examples to the descriptions of the
clientId and locationId properties to improve agent reliability. In the clientId
description, include a specific example ID value (e.g., "123456") to show what a
valid client ID looks like. Similarly, in the locationId description, add a
concrete example ID value (e.g., "1" or another sample location ID) to
demonstrate the expected format. Update both description strings to include
these examples inline within the existing text to help AI agents understand the
expected input format.
- Around line 57-66: The _makeRequest method does not support per-request header
overrides. Add headers as a separate destructured parameter in the _makeRequest
method signature alongside the existing parameters like path, method, params,
and data. Then merge any custom headers passed in with the default headers
returned by this._headers() so that caller-provided headers can override
specific defaults without losing the authentication headers. Pass the merged
headers object to the axios call instead of just calling this._headers()
directly.

---

Duplicate comments:
In `@components/mindbody/mindbody.app.mjs`:
- Line 53: The Authorization header value must include the OAuth 2.0 Bearer
scheme prefix to comply with RFC 6750 standards. Modify the Authorization header
assignment to prepend "Bearer " (with a space after Bearer) before the
oauth_access_token value. This ensures the token is sent in the correct format
expected by the API and aligns with the pattern used throughout the rest of the
codebase.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: e7b955f9-695c-420c-85f3-813fe8b9d60a

📥 Commits

Reviewing files that changed from the base of the PR and between db3d57d and 1b6fdcc.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • components/mindbody/actions/cancel-appointment/cancel-appointment.mjs
  • components/mindbody/actions/get-classes/get-classes.mjs
  • components/mindbody/actions/get-client-details/get-client-details.mjs
  • components/mindbody/actions/upsert-client/upsert-client.mjs
  • components/mindbody/mindbody.app.mjs
  • components/mindbody/package.json

ashwins01
ashwins01 previously approved these changes Jun 16, 2026

@ashwins01 ashwins01 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, moving to QA. Thank you!

@ashwins01

Copy link
Copy Markdown
Contributor

/auto-evals result - ⚠️ converged (no further eval changes) - 5/10 passed, 5 warned (needs human review)

Round App Passed Remaining failures
0 mindbody 5/10 clarifying_question×1

Final: 5/10 passed (5 warned - need human review).

Evals committed to the draft PR: https://github.com/PipedreamHQ/pd-connect-eval-monster/pull/22

@ashwins01

Copy link
Copy Markdown
Contributor

/auto-evals result - ❌ converged (no further eval changes) - 6/10 passed, 1 failed, 0 errored

Round App Passed Remaining failures
0 mindbody 6/10 missing_expected_data×1, clarifying_question×1, tool_error_mcp×1

Final: 6/10 passed (3 warned - need human review).

Evals committed to the draft PR: https://github.com/PipedreamHQ/pd-connect-eval-monster/pull/22

@GTFalcao GTFalcao left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@michelle0927

Copy link
Copy Markdown
Collaborator Author

MCP Eval Results — Mindbody PR #21155

10/10 passing (100%)

# Eval Category Status Tools Time
11 Get Mindbody Site Info read ✅ PASS 1/1 6.4s
12 List Bookable Session Types read ✅ PASS 1/1 17.6s
13 List Staff Members read ✅ PASS 1/1 9.9s
14 Search for Client by Name read ✅ PASS 1/1 9.0s
15 Get Full Client Profile multi-step ✅ PASS 2/1 11.7s
16 List Upcoming Group Classes read ✅ PASS 2/1 10.7s
17 Get Staff Appointments read ✅ PASS 1/1 9.1s
18 Create New Client write ✅ PASS 1/1 7.4s
19 Book Appointment for Client multi-step ✅ PASS 2/1 14.0s
20 Cancel Appointment multi-step ✅ PASS 2/1 10.1s

Model: claude-haiku-4-5-20251001 | Registry: private (published via pd publish)

Notes

  • upsert-client: BirthDate is required by the Mindbody API (YYYY-MM-DDTHH:MM:SS format)
  • book-appointment: Must use an Appointment-type session (not Enrollment); session type 200 + Erik Iversen (staff ID 100000108) confirmed working on the demo site
  • cancel-appointment: Demo site (ID -99) silently accepts status updates without changing state — tool completes without error as expected

@michelle0927 michelle0927 merged commit ebfb179 into PipedreamHQ:master Jun 22, 2026
9 checks passed
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.

mindbody

3 participants