@remit/mcp-server 0.5.2 → 0.7.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.
package/dist/deps.d.ts CHANGED
@@ -20,7 +20,7 @@ export interface McpDeps {
20
20
  message: Pick<IMessageRepository, "get" | "describe">;
21
21
  threadMessage: Pick<IThreadMessageRepository, "listByMailbox" | "listByThread" | "searchByDate">;
22
22
  filter: Pick<IFilterRepository, "listPageByAccountConfig" | "refreshExpiry" | "create" | "get" | "update">;
23
- organizeJobRequest: Pick<IOrganizeJobRequestRepository, "create">;
23
+ organizeJobRequest: Pick<IOrganizeJobRequestRepository, "create" | "get">;
24
24
  storage: Pick<StorageService, "retrieveBodyPart">;
25
25
  bodySync: BodyPartMaterializer;
26
26
  bodySyncQueue: BodySyncCue;
@@ -1,10 +1,10 @@
1
- import { FILTER_NO_ACTION } from "@remit/data-ports";
1
+ import { FILTER_NO_ACTION, } 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";
5
- import { createFilter, listFilters, queueOrganizeJob, refuse, updateFilter, } from "@remit/mailbox-service";
5
+ import { accept, createFilter, listFilters, ownedAccount, queueOrganizeJob, refuse, updateFilter, } from "@remit/mailbox-service";
6
6
  import { z } from "zod";
7
- import { asJson, refused } from "./tool-result.js";
7
+ import { asJson, refused, toolError } from "./tool-result.js";
8
8
  const FILTER_WRITE = {
9
9
  readOnlyHint: false,
10
10
  destructiveHint: false,
@@ -26,6 +26,22 @@ const toFilter = (item) => ({
26
26
  createdAt: item.createdAt,
27
27
  updatedAt: item.updatedAt,
28
28
  });
29
+ const toOrganizeJob = (job) => ({
30
+ organizeJobId: job.organizeJobId,
31
+ state: job.state,
32
+ filterId: job.filterId,
33
+ matchedCount: job.matchedCount,
34
+ appliedCount: job.appliedCount,
35
+ failedCount: job.failedCount,
36
+ errorMessage: job.errorMessage,
37
+ createdAt: job.createdAt,
38
+ updatedAt: job.updatedAt,
39
+ });
40
+ const absentJob = (error) => {
41
+ if (!isNotFoundError(error))
42
+ throw error;
43
+ return null;
44
+ };
29
45
  const notFound = (error) => {
30
46
  if (!isNotFoundError(error))
31
47
  throw error;
@@ -152,4 +168,49 @@ export const registerFilterTools = (server, deps, userId) => {
152
168
  });
153
169
  return asJson({ filter, organizeJobId: job.organizeJobId });
154
170
  });
171
+ server.registerTool("get_organize_job", {
172
+ description: "Read an organize job that applies a filter to existing mail: its state (Pending, Running, Complete, Failed), how many messages it matched, applied and failed, and the error when it failed.",
173
+ inputSchema: {
174
+ organizeJobId: z
175
+ .string()
176
+ .min(1)
177
+ .describe("organizeJobId from create_filter or update_filter"),
178
+ },
179
+ annotations: { readOnlyHint: true, openWorldHint: false },
180
+ }, async ({ organizeJobId }) => {
181
+ const job = await deps.organizeJobRequest
182
+ .get(organizeJobId)
183
+ .catch(absentJob);
184
+ if (!job || job.accountConfigId !== accountConfigId) {
185
+ return toolError(`Organize job not found: ${organizeJobId}. Use the organizeJobId create_filter or update_filter returned.`);
186
+ }
187
+ return asJson(toOrganizeJob(job));
188
+ });
189
+ server.registerTool("apply_filter", {
190
+ description: "Apply a filter to existing mail now, without changing the filter. Queues the same job create_filter queues and returns its organizeJobId.",
191
+ inputSchema: {
192
+ accountId,
193
+ filterId: z.string().min(1).describe("Filter from list_filters"),
194
+ },
195
+ annotations: FILTER_WRITE,
196
+ }, async ({ accountId, filterId }) => {
197
+ const owned = await deps.account
198
+ .get(accountId)
199
+ .then((account) => ownedAccount(account, accountConfigId, "act"))
200
+ .catch(notFound);
201
+ if (!owned.ok)
202
+ return refused(owned.refusal);
203
+ const filter = await deps.filter
204
+ .get(accountConfigId, filterId)
205
+ .then(accept)
206
+ .catch(notFound);
207
+ if (!filter.ok)
208
+ return refused(filter.refusal);
209
+ const job = await queueOrganizeJob(organizeDeps, {
210
+ accountConfigId,
211
+ userId,
212
+ filterId,
213
+ });
214
+ return asJson({ organizeJobId: job.organizeJobId, state: job.state });
215
+ });
155
216
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remit/mcp-server",
3
- "version": "0.5.2",
3
+ "version": "0.7.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": {