@remit/mcp-server 0.8.0 → 0.9.0

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.
@@ -1,4 +1,4 @@
1
- import { FILTER_NO_ACTION, } from "@remit/data-ports";
1
+ import { FILTER_NO_ACTION, FilterRuleV1Schema, filterClausesFromRule, MAX_FILTER_RULE_DEPTH, MAX_FILTER_RULE_LEAVES, } from "@remit/data-ports";
2
2
  import { isNotFoundError } from "@remit/data-ports/errors";
3
3
  import { deriveAccountConfigId } from "@remit/data-ports/id";
4
4
  import { FilterClauseField, FilterMatchOperator, FilterScope, FilterState, } from "@remit/domain-enums";
@@ -18,8 +18,10 @@ const toFilter = (item) => ({
18
18
  expiresAt: item.expiresAt,
19
19
  state: item.state,
20
20
  disabledReason: item.disabledReason,
21
- matchOperator: item.matchOperator,
22
- literalClauses: item.literalClauses,
21
+ ...filterClausesFromRule(item.rule),
22
+ rule: item.rule,
23
+ priority: item.priority,
24
+ stop: item.stop,
23
25
  actionLabelId: item.actionLabelId,
24
26
  actionMailboxId: item.actionMailboxId,
25
27
  ruleChangedAt: item.ruleChangedAt,
@@ -59,7 +61,15 @@ const literalClauses = z
59
61
  .describe("Message attribute the clause matches"),
60
62
  value: z.string().min(1).max(256).describe("Literal text to match"),
61
63
  }))
62
- .min(1);
64
+ .min(1)
65
+ .describe("Literal clauses combined by matchOperator. Send these or rule.");
66
+ const rule = FilterRuleV1Schema.describe(`A Sieve-like test tree. Send this or literalClauses, never both. At most ${MAX_FILTER_RULE_LEAVES} header, address or hasWords tests and ${MAX_FILTER_RULE_DEPTH} levels, counting the top test. Example: {"version":1,"test":{"test":"allof","tests":[{"test":"address","match":"Is","part":"RegistrableDomain","key":"github.com"},{"test":"not","operand":{"test":"header","match":"Contains","header":"Subject","key":"security"}}]}}`);
67
+ const priority = z
68
+ .int()
69
+ .describe("Evaluation order: lower runs first; ties go to the most recently changed filter. The first matching filter with a folder decides the move, and labels add up");
70
+ const stop = z
71
+ .boolean()
72
+ .describe("When true, a message this filter matches is not evaluated against any later filter");
63
73
  const scope = z
64
74
  .enum(FilterScope)
65
75
  .describe("Standing runs until changed; Temporary stops at expiresAt");
@@ -85,7 +95,7 @@ export const registerFilterTools = (server, deps, userId) => {
85
95
  logger: deps.filters.logger,
86
96
  };
87
97
  server.registerTool("list_filters", {
88
- description: "List the user's mail filters: what each matches, where it moves or labels mail, and whether it is on. A page at a time.",
98
+ description: "List the user's mail filters: what each matches (rule, plus literalClauses when the rule is a flat list), its priority and stop, where it moves or labels mail, and whether it is on. A page at a time.",
89
99
  inputSchema: {
90
100
  accountId,
91
101
  continuationToken: z
@@ -107,14 +117,17 @@ export const registerFilterTools = (server, deps, userId) => {
107
117
  });
108
118
  });
109
119
  server.registerTool("create_filter", {
110
- description: "Create a filter that sorts new mail, and queue a job that applies it to existing mail. Returns the filter and the organizeJobId of that job. A target folder must be confirmed by the mail server first.",
120
+ description: "Create a filter that sorts new mail, and queue a job that applies it to existing mail. Match with literalClauses for a flat list, or with rule for not, nesting and exact matches. Returns the filter and the organizeJobId of that job. A target folder must be confirmed by the mail server first.",
111
121
  inputSchema: {
112
122
  accountId,
113
123
  name: z.string().min(1).max(256).describe("Name for the filter"),
114
124
  scope: scope.default(FilterScope.Standing),
115
125
  expiresAt: expiresAt.optional(),
116
126
  matchOperator: matchOperator.default(FilterMatchOperator.And),
117
- literalClauses,
127
+ literalClauses: literalClauses.optional(),
128
+ rule: rule.optional(),
129
+ priority: priority.default(0),
130
+ stop: stop.default(false),
118
131
  actionMailboxId: actionMailboxId.default(FILTER_NO_ACTION),
119
132
  actionLabelId: actionLabelId.default(FILTER_NO_ACTION),
120
133
  },
@@ -129,7 +142,7 @@ export const registerFilterTools = (server, deps, userId) => {
129
142
  });
130
143
  });
131
144
  server.registerTool("update_filter", {
132
- description: "Change a filter: its name, clauses, target folder or label, scope, expiry, or turn it on or off. Only the fields given change. Set applyToExisting to also queue a job that applies the filter to existing mail; its organizeJobId is returned.",
145
+ description: "Change a filter: its name, clauses or rule, priority, stop, target folder or label, scope, expiry, or turn it on or off. Only the fields given change. A filter whose rule has no clause form (literalClauses is empty in list_filters) changes only through rule. Set applyToExisting to also queue a job that applies the filter to existing mail; its organizeJobId is returned.",
133
146
  inputSchema: {
134
147
  accountId,
135
148
  filterId: z.string().min(1).describe("Filter from list_filters"),
@@ -138,6 +151,9 @@ export const registerFilterTools = (server, deps, userId) => {
138
151
  expiresAt: expiresAt.optional(),
139
152
  matchOperator: matchOperator.optional(),
140
153
  literalClauses: literalClauses.optional(),
154
+ rule: rule.optional(),
155
+ priority: priority.optional(),
156
+ stop: stop.optional(),
141
157
  actionMailboxId: actionMailboxId.optional(),
142
158
  actionLabelId: actionLabelId.optional(),
143
159
  state: z
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remit/mcp-server",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "The remit MCP server: mail tools over streamable HTTP and the OAuth authorization server that guards them.",
5
5
  "type": "module",
6
6
  "exports": {