@daeda/mcp-pro 0.1.1 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +109 -7
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4190,31 +4190,76 @@ var batchDeleteRecordsMeta = {
4190
4190
 
4191
4191
  // ../shared/operations/create-list/meta.ts
4192
4192
  import { z as z28 } from "zod";
4193
+ var FilterSchema = z28.object({
4194
+ filterType: z28.string(),
4195
+ property: z28.string().optional(),
4196
+ operation: z28.record(z28.unknown()).optional()
4197
+ }).passthrough();
4198
+ var FilterBranchSchema = z28.object({
4199
+ filterBranchType: z28.enum(["AND", "ASSOCIATION", "UNIFIED_EVENTS"]),
4200
+ filterBranches: z28.lazy(() => z28.array(FilterBranchSchema)).default([]),
4201
+ filters: z28.array(FilterSchema).default([])
4202
+ }).passthrough();
4203
+ var RootFilterBranchSchema = z28.object({
4204
+ filterBranchType: z28.literal("OR"),
4205
+ filterBranches: z28.array(FilterBranchSchema).min(1),
4206
+ filters: z28.array(FilterSchema).default([])
4207
+ }).passthrough();
4193
4208
  var CreateListOperationSchema = z28.object({
4194
4209
  type: z28.literal("create_list"),
4195
4210
  description: z28.string().min(1),
4196
4211
  name: z28.string().min(1),
4197
4212
  object_type_id: z28.string().min(1),
4198
4213
  processing_type: z28.enum(["MANUAL", "DYNAMIC"]),
4199
- filter_branch: z28.record(z28.unknown()).optional()
4214
+ filter_branch: RootFilterBranchSchema.optional()
4200
4215
  });
4216
+ var FILTER_BRANCH_DESCRIPTION = `HubSpot filter definition for DYNAMIC lists. MUST follow the OR\u2192AND hierarchy:
4217
+ - Root: { filterBranchType: "OR", filters: [], filterBranches: [<one or more AND branches>] }
4218
+ - Each AND branch: { filterBranchType: "AND", filters: [<actual filters>], filterBranches: [] }
4219
+ - For OR logic between filter groups, use multiple AND branches under the root OR.
4220
+ - For AND logic within a group, put multiple filters in the same AND branch's filters array.
4221
+ - ASSOCIATION and UNIFIED_EVENTS branches can be nested inside AND branches.
4222
+ Property filter example: { filterType: "PROPERTY", property: "lifecyclestage", operation: { operationType: "MULTISTRING", operator: "IS_EQUAL_TO", values: ["lead"] } }
4223
+ Common operationTypes: MULTISTRING (strings), NUMBER (numbers), BOOL (booleans), ENUMERATION (select/multi-select), ALL_PROPERTY (IS_KNOWN/IS_NOT_KNOWN), TIME_POINT (date comparison), TIME_RANGED (date ranges).`;
4201
4224
  var fields17 = [
4202
4225
  { name: "name", type: "string", required: true, description: "Name for the new list" },
4203
- { name: "object_type_id", type: "string", required: true, description: "Object type ID (e.g. '0-1' for contacts, '0-2' for companies)" },
4226
+ { name: "object_type_id", type: "string", required: true, description: "Object type ID (e.g. '0-1' for contacts, '0-2' for companies, '0-3' for deals)" },
4204
4227
  { name: "processing_type", type: "string", required: true, description: "List type: 'MANUAL' (static) or 'DYNAMIC' (active)" },
4205
- { name: "filter_branch", type: "object", required: false, description: "HubSpot filter definition for DYNAMIC lists (passed as-is to API)" }
4228
+ { name: "filter_branch", type: "object", required: false, description: FILTER_BRANCH_DESCRIPTION }
4206
4229
  ];
4207
4230
  var createListMeta = {
4208
4231
  type: "create_list",
4209
4232
  category: "create",
4210
4233
  summary: "Create a contact or company list (static or dynamic)",
4211
- description: "Create a new HubSpot list. MANUAL lists are static (members added manually). DYNAMIC lists are active (membership determined by filter criteria). For DYNAMIC lists, provide filter_branch with the HubSpot filter definition.",
4234
+ description: `Create a new HubSpot list. MANUAL lists are static (members added manually). DYNAMIC lists are active (membership determined by filter criteria).
4235
+ For DYNAMIC lists, provide filter_branch with the HubSpot filter definition. The root filterBranchType MUST be "OR" with filters: [] and one or more "AND" child branches containing the actual filters. This structure is enforced by HubSpot's API.`,
4212
4236
  fields: fields17,
4213
4237
  example: {
4214
4238
  fields: {
4215
- name: "Hot Leads",
4239
+ name: "Active Leads",
4216
4240
  object_type_id: "0-1",
4217
- processing_type: "MANUAL"
4241
+ processing_type: "DYNAMIC",
4242
+ filter_branch: {
4243
+ filterBranchType: "OR",
4244
+ filters: [],
4245
+ filterBranches: [
4246
+ {
4247
+ filterBranchType: "AND",
4248
+ filterBranches: [],
4249
+ filters: [
4250
+ {
4251
+ filterType: "PROPERTY",
4252
+ property: "lifecyclestage",
4253
+ operation: {
4254
+ operationType: "MULTISTRING",
4255
+ operator: "IS_EQUAL_TO",
4256
+ values: ["lead"]
4257
+ }
4258
+ }
4259
+ ]
4260
+ }
4261
+ ]
4262
+ }
4218
4263
  }
4219
4264
  },
4220
4265
  toNested: (description, fields29) => {
@@ -4230,13 +4275,21 @@ var createListMeta = {
4230
4275
  },
4231
4276
  requiredScopes: () => ["crm.lists.write"],
4232
4277
  getSummary: (op) => `Create List \u2014 ${op.name} (${op.processing_type})`,
4233
- getResourceUrl: (portalId) => `${HUBSPOT_BASE}/contacts/${portalId}/lists`,
4278
+ getResourceUrl: (portalId) => `${HUBSPOT_BASE}/contacts/${portalId}/objectLists/views/all`,
4234
4279
  renderDetails: (op) => {
4235
4280
  const rows = [
4236
4281
  { label: "Name", value: op.name },
4237
4282
  { label: "Object Type ID", value: op.object_type_id },
4238
4283
  { label: "Processing Type", value: op.processing_type }
4239
4284
  ];
4285
+ if (op.filter_branch) {
4286
+ const andCount = op.filter_branch.filterBranches?.length ?? 0;
4287
+ const totalFilters = op.filter_branch.filterBranches?.reduce(
4288
+ (sum, branch) => sum + (branch.filters?.length ?? 0),
4289
+ 0
4290
+ ) ?? 0;
4291
+ rows.push({ label: "Filter Groups", value: `${andCount} group(s), ${totalFilters} filter(s)` });
4292
+ }
4240
4293
  return { rows };
4241
4294
  }
4242
4295
  };
@@ -7027,6 +7080,55 @@ var createListHandler = {
7027
7080
  message: `Processing type '${op.processing_type}' is invalid \u2014 must be "MANUAL" or "DYNAMIC"`
7028
7081
  });
7029
7082
  }
7083
+ if (op.processing_type === "DYNAMIC" && !op.filter_branch) {
7084
+ issues.push({
7085
+ severity: "warning",
7086
+ operation_index: index,
7087
+ code: "DYNAMIC_LIST_NO_FILTER",
7088
+ message: `DYNAMIC list '${op.name}' has no filter_branch \u2014 it will match all records of the object type`
7089
+ });
7090
+ }
7091
+ if (op.filter_branch) {
7092
+ const result = RootFilterBranchSchema.safeParse(op.filter_branch);
7093
+ if (!result.success) {
7094
+ const zodIssues = result.error.issues.map((i) => i.message).join("; ");
7095
+ issues.push({
7096
+ severity: "error",
7097
+ operation_index: index,
7098
+ code: "INVALID_FILTER_BRANCH",
7099
+ message: `filter_branch is invalid: ${zodIssues}. Root must be { filterBranchType: "OR", filters: [], filterBranches: [{ filterBranchType: "AND", filters: [...], filterBranches: [] }] }`
7100
+ });
7101
+ } else {
7102
+ const fb = op.filter_branch;
7103
+ if (fb.filterBranchType !== "OR") {
7104
+ issues.push({
7105
+ severity: "error",
7106
+ operation_index: index,
7107
+ code: "INVALID_FILTER_BRANCH_ROOT",
7108
+ message: `Root filterBranchType must be "OR", got "${fb.filterBranchType}"`
7109
+ });
7110
+ }
7111
+ const branches = fb.filterBranches;
7112
+ const hasAndBranch = branches?.some((b) => b.filterBranchType === "AND");
7113
+ if (!hasAndBranch) {
7114
+ issues.push({
7115
+ severity: "error",
7116
+ operation_index: index,
7117
+ code: "INVALID_FILTER_BRANCH_NO_AND",
7118
+ message: `Root OR branch must contain at least one AND child branch`
7119
+ });
7120
+ }
7121
+ const rootFilters = fb.filters;
7122
+ if (rootFilters && rootFilters.length > 0) {
7123
+ issues.push({
7124
+ severity: "error",
7125
+ operation_index: index,
7126
+ code: "INVALID_FILTER_BRANCH_ROOT_FILTERS",
7127
+ message: `Root OR branch must have an empty filters array \u2014 filters belong inside AND child branches`
7128
+ });
7129
+ }
7130
+ }
7131
+ }
7030
7132
  return issues;
7031
7133
  },
7032
7134
  validateEffectful: (op, index) => pipe42(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@daeda/mcp-pro",
3
- "version": "0.1.1",
3
+ "version": "0.1.4",
4
4
  "description": "MCP server for HubSpot CRM — sync, query, and manage your portal data",
5
5
  "type": "module",
6
6
  "bin": {